0001 /*
0002 * Java Genetic Algorithm Library (jenetics-3.9.0).
0003 * Copyright (c) 2007-2017 Franz Wilhelmstötter
0004 *
0005 * Licensed under the Apache License, Version 2.0 (the "License");
0006 * you may not use this file except in compliance with the License.
0007 * You may obtain a copy of the License at
0008 *
0009 * http://www.apache.org/licenses/LICENSE-2.0
0010 *
0011 * Unless required by applicable law or agreed to in writing, software
0012 * distributed under the License is distributed on an "AS IS" BASIS,
0013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0014 * See the License for the specific language governing permissions and
0015 * limitations under the License.
0016 *
0017 * Author:
0018 * Franz Wilhelmstötter (franz.wilhelmstoetter@gmx.at)
0019 */
0020 package org.jenetics.xml;
0021
0022 import static java.util.Objects.requireNonNull;
0023 import static org.jenetics.xml.stream.Writer.attr;
0024 import static org.jenetics.xml.stream.Writer.elem;
0025 import static org.jenetics.xml.stream.Writer.elems;
0026 import static org.jenetics.xml.stream.Writer.text;
0027
0028 import java.io.OutputStream;
0029 import java.util.Collection;
0030 import java.util.stream.Collectors;
0031
0032 import javax.xml.stream.XMLStreamException;
0033
0034 import org.jenetics.BoundedGene;
0035 import org.jenetics.Chromosome;
0036 import org.jenetics.Gene;
0037 import org.jenetics.xml.stream.AutoCloseableXMLStreamWriter;
0038 import org.jenetics.xml.stream.Writer;
0039 import org.jenetics.xml.stream.XML;
0040
0041 /**
0042 * This class contains static fields and methods, for creating chromosome- and
0043 * genotype writers for different gene types.
0044 *
0045 * <pre>{@code
0046 * final Writer<Genotype<BitGene> bgw =
0047 * Writers.Genotype.writer(Writers.BitChromosome.writer()));
0048 *
0049 * final Writer<Genotype<IntegerGene>> igw =
0050 * Writers.Genotype.writer(Writers.IntegerChromosome.writer()));
0051 *
0052 * final Writer<Genotype<DoubleGene>> dgw =
0053 * Writers.Genotype.writer(Writers.DoubleChromosome.writer()));
0054 * }</pre>
0055 *
0056 * This class also contains some helper methods, which makes it easier to write
0057 * Jenetics domain objects to a given output stream.
0058 * <pre>{@code
0059 * final List<Genotype<BitGene>> genotypes = ...;
0060 * try (OutputStream out = Files.newOutputStream(Paths.get("path"))) {
0061 * Writers.write(out, genotypes, Writers.BitChromosome.writer());
0062 * }
0063 * }</pre>
0064 *
0065 * @author <a href="mailto:franz.wilhelmstoetter@gmx.at">Franz Wilhelmstötter</a>
0066 * @version 3.9
0067 * @since 3.9
0068 */
0069 public final class Writers {
0070 private Writers() {}
0071
0072 /**
0073 * This class contains static writer methods for
0074 * {@link org.jenetics.BitChromosome} objects.
0075 * <p>
0076 * <b>Writer code</b>
0077 * <pre>{@code
0078 * final BitChromosome value = BitChromosome.of(20, 0.5);
0079 * try (AutoCloseableXMLStreamWriter xml = XML.writer(System.out, " ")) {
0080 * Writers.BitChromosome.writer().write(value, xml);
0081 * }
0082 * }</pre>
0083 *
0084 * <b>XML output</b>
0085 * <pre> {@code
0086 * <bit-chromosome length="20" ones-probability="0.5">11100011101011001010</bit-chromosome>
0087 * }</pre>
0088 *
0089 * @author <a href="mailto:franz.wilhelmstoetter@gmx.at">Franz Wilhelmstötter</a>
0090 * @version 3.9
0091 * @since 3.9
0092 */
0093 public static final class BitChromosome {
0094 private BitChromosome() {}
0095
0096 static final String ROOT_NAME = "bit-chromosome";
0097 static final String LENGTH_NAME = "length";
0098 static final String ONES_PROBABILITY_NAME = "ones-probability";
0099
0100 /**
0101 * Return a {@link Writer} for {@link org.jenetics.BitChromosome}
0102 * objects.
0103 *
0104 * @return a chromosome writer
0105 */
0106 public static Writer<org.jenetics.BitChromosome> writer() {
0107 return elem(ROOT_NAME,
0108 attr(LENGTH_NAME).map(org.jenetics.BitChromosome::length),
0109 attr(ONES_PROBABILITY_NAME).map(ch -> ch.getOneProbability()),
0110 text().map(org.jenetics.BitChromosome::toCanonicalString)
0111 );
0112 }
0113
0114 /**
0115 * Write the given {@link org.jenetics.BitChromosome} to the given
0116 * output stream.
0117 *
0118 * @param out the target output stream
0119 * @param data the bit-chromosome to write
0120 * @throws XMLStreamException if an error occurs while writing the
0121 * chromosome
0122 * @throws NullPointerException if one of the given arguments is
0123 * {@code null}
0124 */
0125 public static void write(
0126 final OutputStream out,
0127 final org.jenetics.BitChromosome data
0128 )
0129 throws XMLStreamException
0130 {
0131 requireNonNull(data);
0132 requireNonNull(out);
0133
0134 try (AutoCloseableXMLStreamWriter xml = XML.writer(out)) {
0135 writer().write(xml, data);
0136 }
0137 }
0138 }
0139
0140
0141 /**
0142 * This class contains static writer methods for
0143 * {@link org.jenetics.CharacterChromosome} objects.
0144 * <p>
0145 * <b>Writer code</b>
0146 * <pre>{@code
0147 * final CharacterChromosome value = CharacterChromosome.of("ASDF", CharSeq.of("A-Z"));
0148 * try (AutoCloseableXMLStreamWriter xml = XML.writer(System.out, " ")) {
0149 * Writers.CharacterChromosome.writer().write(value, xml);
0150 * }
0151 * }</pre>
0152 *
0153 * <b>XML output</b>
0154 * <pre> {@code
0155 * <character-chromosome length="4">
0156 * <valid-alleles>ABCDEFGHIJKLMNOPQRSTUVWXYZ<valid-alleles>
0157 * <alleles>ASDF</alleles>
0158 * </character-chromosome>
0159 * }</pre>
0160 */
0161 public static final class CharacterChromosome {
0162 private CharacterChromosome() {}
0163
0164 static final String ROOT_NAME = "character-chromosome";
0165 static final String LENGTH_NAME = "length";
0166 static final String VALID_ALLELES_NAME = "valid-alleles";
0167 static final String ALLELES_NAME = "alleles";
0168
0169 /**
0170 * Return a {@link Writer} for {@link org.jenetics.CharacterChromosome}
0171 * objects.
0172 *
0173 * @return a chromosome writer
0174 */
0175 public static Writer<org.jenetics.CharacterChromosome> writer() {
0176 return elem(ROOT_NAME,
0177 attr(LENGTH_NAME).map(org.jenetics.CharacterChromosome::length),
0178 elem(VALID_ALLELES_NAME,
0179 text().map(ch -> ch.getGene().getValidCharacters())),
0180 elem(ALLELES_NAME,
0181 text().map(org.jenetics.CharacterChromosome::toString))
0182 );
0183 }
0184
0185 /**
0186 * Write the given {@link org.jenetics.CharacterChromosome} to the given
0187 * output stream.
0188 *
0189 * @param out the target output stream
0190 * @param data the chromosome to write
0191 * @param indent the XML level indentation
0192 * @throws XMLStreamException if an error occurs while writing the
0193 * chromosome
0194 * @throws NullPointerException if the {@code chromosome} or output
0195 * stream is {@code null}
0196 */
0197 public static void write(
0198 final OutputStream out,
0199 final org.jenetics.CharacterChromosome data,
0200 final String indent
0201 )
0202 throws XMLStreamException
0203 {
0204 requireNonNull(data);
0205 requireNonNull(out);
0206
0207 try (AutoCloseableXMLStreamWriter xml = XML.writer(out, indent)) {
0208 writer().write(xml, data);
0209 }
0210 }
0211
0212 /**
0213 * Write the given {@link org.jenetics.CharacterChromosome} to the given
0214 * output stream.
0215 *
0216 * @param out the target output stream
0217 * @param data the chromosome to write
0218 * @throws XMLStreamException if an error occurs while writing the
0219 * chromosome
0220 * @throws NullPointerException if the {@code chromosome} or output
0221 * stream is {@code null}
0222 */
0223 public static void write(
0224 final OutputStream out,
0225 final org.jenetics.CharacterChromosome data
0226 )
0227 throws XMLStreamException
0228 {
0229 write(out, data, null);
0230 }
0231
0232 }
0233
0234 /**
0235 * This class contains static writer methods for
0236 * {@link org.jenetics.BoundedChromosome} objects.
0237 *
0238 * <p>
0239 * <b>XML template</b>
0240 * <pre> {@code
0241 * <root-name length="3">
0242 * <min>aaa</min>
0243 * <max>zzz</max>
0244 * <alleles>
0245 * <allele>iii</allele>
0246 * <allele>fff</allele>
0247 * <allele>ggg</allele>
0248 * </alleles>
0249 * </root-name>
0250 * }</pre>
0251 */
0252 public static final class BoundedChromosome {
0253 private BoundedChromosome() {}
0254
0255 static final String LENGTH_NAME = "length";
0256 static final String MIN_NAME = "min";
0257 static final String MAX_NAME = "max";
0258 static final String ALLELE_NAME = "allele";
0259 static final String ALLELES_NAME = "alleles";
0260
0261 /**
0262 * Create a bounded chromosome writer with the given configuration.
0263 *
0264 * @param rootName the name of the root element. E.g. {@code int-chromosome}
0265 * @param alleleWriter the XML writer used for the alleles
0266 * @param <A> the allele type
0267 * @param <G> the bounded gene type
0268 * @param <C> the bounded chromosome type
0269 * @return a bounded chromosome XML writer
0270 * @throws NullPointerException if one of the arguments is {@code null}
0271 */
0272 public static <
0273 A extends Comparable<? super A>,
0274 G extends BoundedGene<A, G>,
0275 C extends org.jenetics.BoundedChromosome<A, G>
0276 >
0277 Writer<C> writer(
0278 final String rootName,
0279 final Writer<? super A> alleleWriter
0280 ) {
0281 requireNonNull(rootName);
0282 requireNonNull(alleleWriter);
0283
0284 return elem(rootName,
0285 attr(LENGTH_NAME).map(ch -> ch.length()),
0286 elem(MIN_NAME, alleleWriter.map(ch -> ch.getMin())),
0287 elem(MAX_NAME, alleleWriter.map(ch -> ch.getMax())),
0288 elem(ALLELES_NAME,
0289 elems(ALLELE_NAME, alleleWriter)
0290 .map(ch -> ch.toSeq().map(G::getAllele))
0291 )
0292 );
0293 }
0294 }
0295
0296 /**
0297 * This class contains static writer methods for
0298 * {@link org.jenetics.IntegerChromosome} objects.
0299 * <p>
0300 * <b>Writer code</b>
0301 * <pre>{@code
0302 * final IntegerChromosome value = IntegerChromosome
0303 * .of(Integer.MIN_VALUE, Integer.MAX_VALUE, 3);
0304 * try (AutoCloseableXMLStreamWriter xml = XML.writer(System.out, " ")) {
0305 * Writers.IntegerChromosome.writer().write(value, xml);
0306 * }
0307 * }</pre>
0308 *
0309 * <b>XML output</b>
0310 * <pre> {@code
0311 * <int-chromosome length="3">
0312 * <min>-2147483648</min>
0313 * <max>2147483647</max>
0314 * <alleles>
0315 * <allele>-1878762439</allele>
0316 * <allele>-957346595</allele>
0317 * <allele>-88668137</allele>
0318 * </alleles>
0319 * </int-chromosome>
0320 * }</pre>
0321 */
0322 public static final class IntegerChromosome {
0323 private IntegerChromosome() {}
0324
0325 static final String ROOT_NAME = "int-chromosome";
0326
0327 /**
0328 * Return the default integer allele writer for the
0329 * {@code IntegerChromosome}.
0330 *
0331 * @return the default integer allele writer
0332 */
0333 public static Writer<Integer> alleleWriter() {
0334 return text();
0335 }
0336
0337 /**
0338 * Return a {@link Writer} for {@link org.jenetics.IntegerChromosome}
0339 * objects.
0340 *
0341 * @param alleleWriter the allele writer used for writing the integer
0342 * allele. Might be useful for using different integer
0343 * <i>encodings</i>.
0344 * @return a chromosome writer
0345 * @throws NullPointerException if the given {@code alleleWriter} is
0346 * {@code null}
0347 */
0348 public static Writer<org.jenetics.IntegerChromosome>
0349 writer(final Writer<? super Integer> alleleWriter) {
0350 requireNonNull(alleleWriter);
0351
0352 return BoundedChromosome.writer(ROOT_NAME, alleleWriter);
0353 }
0354
0355 /**
0356 * Return a {@link Writer} for {@link org.jenetics.IntegerChromosome}
0357 * objects.
0358 *
0359 * @return a chromosome writer
0360 */
0361 public static Writer<org.jenetics.IntegerChromosome> writer() {
0362 return writer(alleleWriter());
0363 }
0364
0365 /**
0366 * Write the given {@link org.jenetics.IntegerChromosome} to the given
0367 * output stream.
0368 *
0369 * @param out the target output stream
0370 * @param data the chromosome to write
0371 * @param indent the XML level indentation
0372 * @throws XMLStreamException if an error occurs while writing the
0373 * chromosome
0374 * @throws NullPointerException if the {@code chromosome} or output
0375 * stream is {@code null}
0376 */
0377 public static void write(
0378 final OutputStream out,
0379 final org.jenetics.IntegerChromosome data,
0380 final String indent
0381 )
0382 throws XMLStreamException
0383 {
0384 requireNonNull(data);
0385 requireNonNull(out);
0386
0387 try (AutoCloseableXMLStreamWriter xml = XML.writer(out, indent)) {
0388 writer().write(xml, data);
0389 }
0390 }
0391
0392 /**
0393 * Write the given {@link org.jenetics.IntegerChromosome} to the given
0394 * output stream.
0395 *
0396 * @param out the target output stream
0397 * @param data the chromosome to write
0398 * @throws XMLStreamException if an error occurs while writing the
0399 * chromosome
0400 * @throws NullPointerException if the {@code chromosome} or output
0401 * stream is {@code null}
0402 */
0403 public static void write(
0404 final OutputStream out,
0405 final org.jenetics.IntegerChromosome data
0406 )
0407 throws XMLStreamException
0408 {
0409 write(out, data, null);
0410 }
0411 }
0412
0413 /**
0414 * This class contains static writer methods for
0415 * {@link org.jenetics.LongChromosome} objects.
0416 * <p>
0417 * <b>Writer code</b>
0418 * <pre>{@code
0419 * final LongChromosome value = LongChromosome
0420 * .of(Long.MIN_VALUE, Long.MAX_VALUE, 3);
0421 * try (AutoCloseableXMLStreamWriter xml = XML.writer(System.out, " ")) {
0422 * Writers.LongChromosome.writer().write(value, xml);
0423 * }
0424 * }</pre>
0425 *
0426 * <b>XML output</b>
0427 * <pre> {@code
0428 * <long-chromosome length="3">
0429 * <min>-9223372036854775808</min>
0430 * <max>9223372036854775807</max>
0431 * <alleles>
0432 * <allele>-1345217698116542402</allele>
0433 * <allele>-7144755673073475303</allele>
0434 * <allele>6053786736809578435</allele>
0435 * </alleles>
0436 * </long-chromosome>
0437 * }</pre>
0438 */
0439 public static final class LongChromosome {
0440 private LongChromosome() {}
0441
0442 static final String ROOT_NAME = "long-chromosome";
0443
0444 /**
0445 * Return the default long allele writer for the
0446 * {@code IntegerChromosome}.
0447 *
0448 * @return the default long allele writer
0449 */
0450 public static Writer<Long> alleleWriter() {
0451 return Writer.text();
0452 }
0453
0454 /**
0455 * Return a {@link Writer} for {@link org.jenetics.LongChromosome}
0456 * objects.
0457 *
0458 * @param alleleWriter the allele writer used for writing the long
0459 * allele. Might be useful for using different long
0460 * <i>encodings</i>.
0461 * @return a chromosome writer
0462 * @throws NullPointerException if the given {@code alleleWriter} is
0463 * {@code null}
0464 */
0465 public static Writer<org.jenetics.LongChromosome>
0466 writer(final Writer<? super Long> alleleWriter) {
0467 return BoundedChromosome.writer(ROOT_NAME, alleleWriter);
0468 }
0469
0470 /**
0471 * Return a {@link Writer} for {@link org.jenetics.LongChromosome}
0472 * objects.
0473 *
0474 * @return a chromosome writer
0475 */
0476 public static Writer<org.jenetics.LongChromosome> writer() {
0477 return writer(alleleWriter());
0478 }
0479
0480 /**
0481 * Write the given {@link org.jenetics.LongChromosome} to the given
0482 * output stream.
0483 *
0484 * @param out the target output stream
0485 * @param data the chromosome to write
0486 * @param indent the XML level indentation
0487 * @throws XMLStreamException if an error occurs while writing the
0488 * chromosome
0489 * @throws NullPointerException if the {@code chromosome} or output
0490 * stream is {@code null}
0491 */
0492 public static void write(
0493 final OutputStream out,
0494 final org.jenetics.LongChromosome data,
0495 final String indent
0496 )
0497 throws XMLStreamException
0498 {
0499 requireNonNull(data);
0500 requireNonNull(out);
0501
0502 try (AutoCloseableXMLStreamWriter xml = XML.writer(out, indent)) {
0503 writer().write(xml, data);
0504 }
0505 }
0506
0507 /**
0508 * Write the given {@link org.jenetics.LongChromosome} to the given
0509 * output stream.
0510 *
0511 * @param out the target output stream
0512 * @param data the chromosome to write
0513 * @throws XMLStreamException if an error occurs while writing the
0514 * chromosome
0515 * @throws NullPointerException if the {@code chromosome} or output
0516 * stream is {@code null}
0517 */
0518 public static void write(
0519 final OutputStream out,
0520 final org.jenetics.LongChromosome data
0521 )
0522 throws XMLStreamException
0523 {
0524 write(out, data, null);
0525 }
0526 }
0527
0528 /**
0529 * This class contains static writer methods for
0530 * {@link org.jenetics.DoubleChromosome} objects.
0531 * <p>
0532 * <b>Writer code</b>
0533 * <pre>{@code
0534 * final DoubleChromosome value = DoubleChromosome.of(0.0, 1.0, 3);
0535 * try (AutoCloseableXMLStreamWriter xml = XML.writer(System.out, " ")) {
0536 * Writers.DoubleChromosome.writer().write(value, xml);
0537 * }
0538 * }</pre>
0539 *
0540 * <b>XML output</b>
0541 * <pre> {@code
0542 * <double-chromosome length="3">
0543 * <min>0.0</min>
0544 * <max>1.0</max>
0545 * <alleles>
0546 * <allele>0.27251556008507416</allele>
0547 * <allele>0.003140816229067145</allele>
0548 * <allele>0.43947528327497376</allele>
0549 * </alleles>
0550 * </double-chromosome>
0551 * }</pre>
0552 */
0553 public static final class DoubleChromosome
0554 //extends WriterProvider<org.jenetics.DoubleChromosome>
0555 {
0556 private DoubleChromosome() {}
0557
0558 static final String ROOT_NAME = "double-chromosome";
0559
0560 /**
0561 * Return the default double allele writer for the
0562 * {@code DoubleChromosome}.
0563 *
0564 * @return the default double allele writer
0565 */
0566 public static Writer<Double> alleleWriter() {
0567 return text().map(Object::toString);
0568 }
0569
0570 /**
0571 * Return a {@link Writer} for {@link org.jenetics.DoubleChromosome}
0572 * objects.
0573 *
0574 * @param alleleWriter the allele writer used for writing the long
0575 * allele. Might be useful for using different long
0576 * <i>encodings</i>.
0577 * @return a chromosome writer
0578 * @throws NullPointerException if the given {@code alleleWriter} is
0579 * {@code null}
0580 */
0581 public static Writer<org.jenetics.DoubleChromosome>
0582 writer(final Writer<? super Double> alleleWriter) {
0583 return BoundedChromosome.writer(ROOT_NAME, alleleWriter);
0584 }
0585
0586 /**
0587 * Return a {@link Writer} for {@link org.jenetics.DoubleChromosome}
0588 * objects.
0589 *
0590 * @return a chromosome writer
0591 */
0592 public static Writer<org.jenetics.DoubleChromosome> writer() {
0593 return writer(alleleWriter());
0594 }
0595
0596 public Class<org.jenetics.DoubleChromosome> type() {
0597 return org.jenetics.DoubleChromosome.class;
0598 }
0599
0600 /**
0601 * Write the given {@link org.jenetics.DoubleChromosome} to the given
0602 * output stream.
0603 *
0604 * @param out the target output stream
0605 * @param data the chromosome to write
0606 * @param indent the XML level indentation
0607 * @throws XMLStreamException if an error occurs while writing the
0608 * chromosome
0609 * @throws NullPointerException if the {@code chromosome} or output
0610 * stream is {@code null}
0611 */
0612 public static void write(
0613 final OutputStream out,
0614 final org.jenetics.DoubleChromosome data,
0615 final String indent
0616 )
0617 throws XMLStreamException
0618 {
0619 requireNonNull(data);
0620 requireNonNull(out);
0621
0622 try (AutoCloseableXMLStreamWriter xml = XML.writer(out, indent)) {
0623 writer().write(xml, data);
0624 }
0625 }
0626
0627 /**
0628 * Write the given {@link org.jenetics.DoubleChromosome} to the given
0629 * output stream.
0630 *
0631 * @param out the target output stream
0632 * @param data the chromosome to write
0633 * @throws XMLStreamException if an error occurs while writing the
0634 * chromosome
0635 * @throws NullPointerException if the {@code chromosome} or output
0636 * stream is {@code null}
0637 */
0638 public static void write(
0639 final OutputStream out,
0640 final org.jenetics.DoubleChromosome data
0641 )
0642 throws XMLStreamException
0643 {
0644 write(out, data, null);
0645 }
0646 }
0647
0648 /**
0649 * This class contains static writer methods for
0650 * {@link org.jenetics.PermutationChromosome} objects.
0651 * <p>
0652 * <b>Writer code</b>
0653 * <pre>{@code
0654 * final PermutationChromosome<Integer> value =
0655 * PermutationChromosome.ofInteger(5)
0656 *
0657 * final Writer<PermutationChromosome<Integer> writer =
0658 * Writers.PermutationChromosome.writer();
0659 *
0660 * try (AutoCloseableXMLStreamWriter xml = XML.writer(System.out, " ")) {
0661 * Writers.PermutationChromosome.writer().write(value, xml);
0662 * }
0663 * }</pre>
0664 *
0665 * <b>XML output</b>
0666 * <pre> {@code
0667 * <permutation-chromosome length="5">
0668 * <valid-alleles type="java.lang.Integer">
0669 * <allele>0</allele>
0670 * <allele>1</allele>
0671 * <allele>2</allele>
0672 * <allele>3</allele>
0673 * <allele>4</allele>
0674 * </valid-alleles>
0675 * <order>2 1 3 5 4</order>
0676 * </permutation-chromosome>
0677 * }</pre>
0678 */
0679 public static final class PermutationChromosome {
0680 private PermutationChromosome() {}
0681
0682 static final String ROOT_NAME = "permutation-chromosome";
0683 static final String LENGTH_NAME = "length";
0684 static final String VALID_ALLELES_NAME = "valid-alleles";
0685 static final String ALLELE_NAME = "allele";
0686 static final String ORDER_NAME = "order";
0687
0688 /**
0689 * Create a writer for permutation-chromosomes. How to write the valid
0690 * alleles is defined by the given {@link Writer}.
0691 *
0692 * @param alleleWriter the allele writer
0693 * @param <A> the allele type
0694 * @return a new permutation chromosome writer
0695 * @throws NullPointerException if the given allele {@code writer} is
0696 * {@code null}
0697 */
0698 public static <A> Writer<org.jenetics.PermutationChromosome<A>>
0699 writer(final Writer<? super A> alleleWriter) {
0700 return elem(ROOT_NAME,
0701 attr(LENGTH_NAME).map(org.jenetics.PermutationChromosome::length),
0702 elem(VALID_ALLELES_NAME,
0703 attr("type").map(PermutationChromosome::toAlleleTypeName),
0704 elems(ALLELE_NAME, alleleWriter)
0705 .map(ch -> ch.getValidAlleles())
0706 ),
0707 elem(ORDER_NAME, text())
0708 .map(ch -> ch.stream()
0709 .map(g -> Integer.toString(g.getAlleleIndex()))
0710 .collect(Collectors.joining(" ")))
0711 );
0712 }
0713
0714 private static String toAlleleTypeName(
0715 final org.jenetics.PermutationChromosome<?> ch
0716 ) {
0717 return ch.getGene().getAllele().getClass().getCanonicalName();
0718 }
0719
0720 /**
0721 * Create a writer for permutation-chromosomes. The valid alleles are
0722 * serialized by calling the {@link Object#toString()} method. Calling
0723 * this method is equivalent with:
0724 * <pre>{@code
0725 * final Writer<PermutationChromosome<Double> writer =
0726 * PermutationChromosome.write(text().map(Objects::toString));
0727 * }</pre>
0728 *
0729 * Example output:
0730 * <pre> {@code
0731 * <permutation-chromosome length="15">
0732 * <valid-alleles type="java.lang.Double">
0733 * <allele>0.27251556008507416</allele>
0734 * <allele>0.003140816229067145</allele>
0735 * <allele>0.43947528327497376</allele>
0736 * <allele>0.10654807463069327</allele>
0737 * <allele>0.19696530915810317</allele>
0738 * <allele>0.7450003838065538</allele>
0739 * <allele>0.5594416969271359</allele>
0740 * <allele>0.02823782430152355</allele>
0741 * <allele>0.5741102315010789</allele>
0742 * <allele>0.4533651041367144</allele>
0743 * <allele>0.811148141800367</allele>
0744 * <allele>0.5710456351848858</allele>
0745 * <allele>0.30166768355230955</allele>
0746 * <allele>0.5455492865240272</allele>
0747 * <allele>0.21068427527733102</allele>
0748 * </valid-alleles>
0749 * <order>13 12 4 6 8 14 7 2 11 5 3 0 9 10 1</order>
0750 * </permutation-chromosome>
0751 * }</pre>
0752 *
0753 * @param <A> the allele type
0754 * @return a new permutation chromosome writer
0755 */
0756 public static <A> Writer<org.jenetics.PermutationChromosome<A>> writer() {
0757 return writer(text());
0758 }
0759
0760 /**
0761 * Write the given {@link org.jenetics.PermutationChromosome} to the
0762 * given output stream.
0763 *
0764 * @param <A> the allele type
0765 * @param out the target output stream
0766 * @param data the chromosome to write
0767 * @param indent the XML level indentation
0768 * @throws XMLStreamException if an error occurs while writing the
0769 * chromosome
0770 * @throws NullPointerException if the {@code chromosome} or output
0771 * stream is {@code null}
0772 */
0773 public static <A> void write(
0774 final OutputStream out,
0775 final org.jenetics.PermutationChromosome<A> data,
0776 final String indent
0777 )
0778 throws XMLStreamException
0779 {
0780 requireNonNull(data);
0781 requireNonNull(out);
0782
0783 try (AutoCloseableXMLStreamWriter writer = XML.writer(out, indent)) {
0784 PermutationChromosome.<A>writer().write(writer, data);
0785 }
0786 }
0787
0788 /**
0789 * Write the given {@link org.jenetics.PermutationChromosome} to the
0790 * given output stream.
0791 *
0792 * @param <A> the allele type
0793 * @param out the target output stream
0794 * @param data the chromosome to write
0795 * @param indent the XML level indentation
0796 * @param alleleWriter the allele writer of the permutation chromosome
0797 * @throws XMLStreamException if an error occurs while writing the
0798 * chromosome
0799 * @throws NullPointerException if the {@code chromosome} or output
0800 * stream is {@code null}
0801 */
0802 public static <A> void write(
0803 final OutputStream out,
0804 final org.jenetics.PermutationChromosome<A> data,
0805 final String indent,
0806 final Writer<? super A> alleleWriter
0807 )
0808 throws XMLStreamException
0809 {
0810 requireNonNull(data);
0811 requireNonNull(alleleWriter);
0812 requireNonNull(out);
0813
0814 try (AutoCloseableXMLStreamWriter xml = XML.writer(out, indent)) {
0815 PermutationChromosome.<A>writer(alleleWriter)
0816 .write(xml, data);
0817 }
0818 }
0819
0820 /**
0821 * Write the given {@link org.jenetics.PermutationChromosome} to the
0822 * given output stream.
0823 *
0824 * @param <A> the allele type
0825 * @param out the target output stream
0826 * @param data the chromosome to write
0827 * @throws XMLStreamException if an error occurs while writing the
0828 * chromosome
0829 * @throws NullPointerException if the {@code chromosome} or output
0830 * stream is {@code null}
0831 */
0832 public static <A> void write(
0833 final OutputStream out,
0834 final org.jenetics.PermutationChromosome<A> data
0835 )
0836 throws XMLStreamException
0837 {
0838 write(out, data, null, text());
0839 }
0840
0841 /**
0842 * Write the given {@link org.jenetics.PermutationChromosome} to the
0843 * given output stream.
0844 *
0845 * @param <A> the allele type
0846 * @param out the target output stream
0847 * @param data the chromosome to write
0848 * @param alleleWriter the allele writer used to write the chromosome
0849 * alleles
0850 * @throws XMLStreamException if an error occurs while writing the
0851 * chromosome
0852 * @throws NullPointerException if the {@code chromosome} or output
0853 * stream is {@code null}
0854 */
0855 public static <A> void write(
0856 final OutputStream out,
0857 final org.jenetics.PermutationChromosome<A> data,
0858 final Writer<? super A> alleleWriter
0859 )
0860 throws XMLStreamException
0861 {
0862 write(out, data, null, alleleWriter);
0863 }
0864
0865 }
0866
0867 /**
0868 * This class contains static writer methods for
0869 * {@link org.jenetics.Genotype} objects.
0870 * <p>
0871 * <b>Writer code</b>
0872 * <pre>{@code
0873 * final Genotype<DoubleGene> gt = Genotype.of(
0874 * DoubleChromosome.of(0.0, 1.0, 3),
0875 * DoubleChromosome.of(0.0, 1.0, 2)
0876 * );
0877 * final Writer<Genotype<DoubleGene>> writer =
0878 * Writers.Genotype.writer(Writers.DoubleChromosome.writer());
0879 *
0880 * try (AutoCloseableXMLStreamWriter xml = XML.writer(System.out, " ")) {
0881 * writer.write(value, xml);
0882 * }
0883 * }</pre>
0884 *
0885 * <b>XML output</b>
0886 * <pre> {@code
0887 * <genotype length="2" ngenes="5">
0888 * <double-chromosome length="3">
0889 * <min>0.0</min>
0890 * <max>1.0</max>
0891 * <alleles>
0892 * <allele>0.27251556008507416</allele>
0893 * <allele>0.003140816229067145</allele>
0894 * <allele>0.43947528327497376</allele>
0895 * </alleles>
0896 * </double-chromosome>
0897 * <double-chromosome length="2">
0898 * <min>0.0</min>
0899 * <max>1.0</max>
0900 * <alleles>
0901 * <allele>0.4026521545744768</allele>
0902 * <allele>0.36137605952663554</allele>
0903 * <alleles>
0904 * </double-chromosome>
0905 * </genotype>
0906 * }</pre>
0907 */
0908 public static final class Genotype {
0909 private Genotype() {}
0910
0911 static final String ROOT_NAME = "genotype";
0912 static final String LENGTH_NAME = "length";
0913 static final String NGENES_NAME = "ngenes";
0914
0915 /**
0916 * Create a writer for genotypes of arbitrary chromosomes. How to write the
0917 * genotypes chromosomes is defined by the given {@link Writer}.
0918 *
0919 * @param writer the chromosome writer
0920 * @param <A> the allele type
0921 * @param <G> the gene type
0922 * @param <C> the chromosome type
0923 * @return a new genotype writer
0924 * @throws NullPointerException if the given chromosome {@code writer} is
0925 * {@code null}
0926 */
0927 public static <
0928 A,
0929 G extends Gene<A, G>,
0930 C extends Chromosome<G>
0931 >
0932 Writer<org.jenetics.Genotype<G>> writer(final Writer<? super C> writer) {
0933 return elem(
0934 ROOT_NAME,
0935 attr(LENGTH_NAME).map(org.jenetics.Genotype<G>::length),
0936 attr(NGENES_NAME).map(org.jenetics.Genotype<G>::getNumberOfGenes),
0937 elems(writer).map(gt -> cast(gt.toSeq()))
0938 );
0939 }
0940
0941 @SuppressWarnings("unchecked")
0942 private static <A, B> B cast(final A value) {
0943 return (B)value;
0944 }
0945
0946 /**
0947 * Write the given {@link org.jenetics.Genotype} to the given output
0948 * stream.
0949 *
0950 * @param <A> the allele type
0951 * @param <G> the gene type
0952 * @param <C> the chromosome type
0953 * @param out the target output stream
0954 * @param data the genotype to write
0955 * @param indent the XML level indentation
0956 * @param chromosomeWriter the chromosome writer used to write the
0957 * genotypes
0958 * @throws XMLStreamException if an error occurs while writing the
0959 * chromosome
0960 * @throws NullPointerException if the one of the arguments is
0961 * {@code null}
0962 */
0963 public static <
0964 A,
0965 G extends Gene<A, G>,
0966 C extends Chromosome<G>
0967 >
0968 void write(
0969 final OutputStream out,
0970 final org.jenetics.Genotype<G> data,
0971 final String indent,
0972 final Writer<? super C> chromosomeWriter
0973 )
0974 throws XMLStreamException
0975 {
0976 requireNonNull(data);
0977 requireNonNull(chromosomeWriter);
0978 requireNonNull(out);
0979
0980 try (AutoCloseableXMLStreamWriter writer = XML.writer(out, indent)) {
0981 Genotype.<A, G, C>writer(chromosomeWriter).write(writer, data);
0982 }
0983 }
0984
0985 /**
0986 * Write the given {@link org.jenetics.Genotype} to the given output
0987 * stream.
0988 *
0989 * @param <A> the allele type
0990 * @param <G> the gene type
0991 * @param <C> the chromosome type
0992 * @param out the target output stream
0993 * @param data the genotype to write
0994 * @param chromosomeWriter the chromosome writer used to write the
0995 * genotypes
0996 * @throws XMLStreamException if an error occurs while writing the
0997 * chromosome
0998 * @throws NullPointerException if the one of the arguments is
0999 * {@code null}
1000 */
1001 public static <
1002 A,
1003 G extends Gene<A, G>,
1004 C extends Chromosome<G>
1005 >
1006 void write(
1007 final OutputStream out,
1008 final org.jenetics.Genotype<G> data,
1009 final Writer<? super C> chromosomeWriter
1010 )
1011 throws XMLStreamException
1012 {
1013 requireNonNull(data);
1014 requireNonNull(chromosomeWriter);
1015 requireNonNull(out);
1016
1017 try (AutoCloseableXMLStreamWriter xml = XML.writer(out)) {
1018 Genotype.<A, G, C>writer(chromosomeWriter).write(xml, data);
1019 }
1020 }
1021
1022 }
1023
1024 /**
1025 * This class contains static writer methods for
1026 * {@link org.jenetics.Genotype} objects.
1027 * <p>
1028 * <b>Writer code</b>
1029 * <pre>{@code
1030 * final Genotype<DoubleGene> gt = Genotype.of(
1031 * DoubleChromosome.of(0.0, 1.0, 3),
1032 * DoubleChromosome.of(0.0, 1.0, 2)
1033 * );
1034 *
1035 * final Writer<Collection<Genotype<DoubleGene>>> writer =
1036 * Writers.Genotypes.writer(Writers.DoubleChromosome.writer());
1037 *
1038 * try (AutoCloseableXMLStreamWriter xml = XML.writer(System.out, " ")) {
1039 * writer.write(asList(value), xml);
1040 * }
1041 * }</pre>
1042 *
1043 * <pre> {@code
1044 * <genotypes length="1">
1045 * <genotype length="2" ngenes="5">
1046 * <double-chromosome length="3">
1047 * <min>0.0</min>
1048 * <max>1.0</max>
1049 * <alleles>
1050 * <allele>0.27251556008507416</allele>
1051 * <allele>0.003140816229067145</allele>
1052 * <allele>0.43947528327497376</allele>
1053 * </alleles>
1054 * </double-chromosome>
1055 * <double-chromosome length="2">
1056 * <min>0.0</min>
1057 * <max>1.0</max>
1058 * <alleles>
1059 * <allele>0.4026521545744768</allele>
1060 * <allele>0.36137605952663554</allele>
1061 * <alleles>
1062 * </double-chromosome>
1063 * </genotype>
1064 * </genotypes>
1065 * }</pre>
1066 */
1067 public static final class Genotypes {
1068 private Genotypes() {}
1069
1070 static final String ROOT_NAME = "genotypes";
1071 static final String LENGTH_NAME = "length";
1072
1073 /**
1074 * Create a writer for genotypes of arbitrary chromosomes. How to write the
1075 * genotypes chromosomes is defined by the given {@link Writer}. The
1076 * following writer allows to write double-gene chromosomes:
1077 * <pre>{@code
1078 * final Writer<Collection<Genotype<DoubleGene>>> writer =
1079 * Writers.Genotypes.writer(Writers.DoubleChromosome.writer());
1080 * }</pre>
1081 *
1082 * @param writer the chromosome writer
1083 * @param <A> the allele type
1084 * @param <G> the gene type
1085 * @param <C> the chromosome type
1086 * @return a new genotype writer
1087 * @throws NullPointerException if the given chromosome {@code writer} is
1088 * {@code null}
1089 */
1090 public static <
1091 A,
1092 G extends Gene<A, G>,
1093 C extends Chromosome<G>
1094 >
1095 Writer<Collection<org.jenetics.Genotype<G>>>
1096 writer(final Writer<? super C> writer) {
1097 return elem(
1098 ROOT_NAME,
1099 attr(LENGTH_NAME).map(Collection::size),
1100 elems(Genotype.writer(writer))
1101 );
1102 }
1103
1104 /**
1105 * Write the given {@link org.jenetics.Genotype} to the given output
1106 * stream.
1107 *
1108 * @param <A> the allele type
1109 * @param <G> the gene type
1110 * @param <C> the chromosome type
1111 * @param out the target output stream
1112 * @param data the genotypes to write
1113 * @param indent the XML level indentation
1114 * @param chromosomeWriter the chromosome writer used to write the
1115 * genotypes
1116 * @throws XMLStreamException if an error occurs while writing the
1117 * chromosome
1118 * @throws NullPointerException if the one of the arguments is
1119 * {@code null}
1120 */
1121 public static <
1122 A,
1123 G extends Gene<A, G>,
1124 C extends Chromosome<G>
1125 >
1126 void write(
1127 final OutputStream out,
1128 final Collection<org.jenetics.Genotype<G>> data,
1129 final String indent,
1130 final Writer<? super C> chromosomeWriter
1131 )
1132 throws XMLStreamException
1133 {
1134 requireNonNull(data);
1135 requireNonNull(chromosomeWriter);
1136 requireNonNull(out);
1137
1138 try (AutoCloseableXMLStreamWriter xml = XML.writer(out, indent)) {
1139 Genotypes.<A, G, C>writer(chromosomeWriter).write(xml, data);
1140 }
1141 }
1142
1143 /**
1144 * Write the given {@link org.jenetics.Genotype} to the given output
1145 * stream.
1146 *
1147 * @param <A> the allele type
1148 * @param <G> the gene type
1149 * @param <C> the chromosome type
1150 * @param out the target output stream
1151 * @param data the genotypes to write
1152 * @param chromosomeWriter the chromosome writer used to write the
1153 * genotypes
1154 * @throws XMLStreamException if an error occurs while writing the
1155 * chromosome
1156 * @throws NullPointerException if the one of the arguments is
1157 * {@code null}
1158 */
1159 public static <
1160 A,
1161 G extends Gene<A, G>,
1162 C extends Chromosome<G>
1163 >
1164 void write(
1165 final OutputStream out,
1166 final Collection<org.jenetics.Genotype<G>> data,
1167 final Writer<? super C> chromosomeWriter
1168 )
1169 throws XMLStreamException
1170 {
1171 requireNonNull(data);
1172 requireNonNull(chromosomeWriter);
1173 requireNonNull(out);
1174
1175 try (AutoCloseableXMLStreamWriter xml = XML.writer(out)) {
1176 Genotypes.<A, G, C>writer(chromosomeWriter).write(xml, data);
1177 }
1178 }
1179
1180 }
1181
1182
1183 /**
1184 * Write the given {@link org.jenetics.Genotype} to the given output
1185 * stream.
1186 *
1187 * @see Genotypes#write(OutputStream, Collection, Writer)
1188 *
1189 * @param <A> the allele type
1190 * @param <G> the gene type
1191 * @param <C> the chromosome type
1192 * @param out the target output stream
1193 * @param data the genotypes to write
1194 * @param chromosomeWriter the chromosome writer used to write the
1195 * genotypes
1196 * @throws XMLStreamException if an error occurs while writing the
1197 * chromosome
1198 * @throws NullPointerException if the one of the arguments is
1199 * {@code null}
1200 */
1201 public static <
1202 A,
1203 G extends Gene<A, G>,
1204 C extends Chromosome<G>
1205 >
1206 void write(
1207 final OutputStream out,
1208 final Collection<org.jenetics.Genotype<G>> data,
1209 final Writer<? super C> chromosomeWriter
1210 )
1211 throws XMLStreamException
1212 {
1213 Genotypes.write(out, data, chromosomeWriter);
1214 }
1215
1216 }
|