001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.commons.geometry.io.euclidean.threed.txt;
018
019import java.nio.charset.Charset;
020import java.nio.charset.StandardCharsets;
021import java.util.Iterator;
022import java.util.function.DoubleFunction;
023import java.util.stream.Stream;
024
025import org.apache.commons.geometry.euclidean.threed.PlaneConvexSubset;
026import org.apache.commons.geometry.io.core.internal.GeometryIOUtils;
027import org.apache.commons.geometry.io.core.output.GeometryOutput;
028import org.apache.commons.geometry.io.euclidean.threed.AbstractBoundaryWriteHandler3D;
029import org.apache.commons.geometry.io.euclidean.threed.FacetDefinition;
030
031/** Abstract based class for write handlers that output text formats produced
032 * by {@link TextFacetDefinitionWriter}.
033 * @see TextFacetDefinitionWriter
034 */
035public abstract class AbstractTextBoundaryWriteHandler3D extends AbstractBoundaryWriteHandler3D {
036
037    /** The default line separator value. */
038    private static final String DEFAULT_LINE_SEPARATOR = "\n";
039
040    /** Default charset used for text output. */
041    private Charset defaultCharset = StandardCharsets.UTF_8;
042
043    /** Line separator string. */
044    private String lineSeparator = DEFAULT_LINE_SEPARATOR;
045
046    /** Double format function. */
047    private DoubleFunction<String> doubleFormat = Double::toString;
048
049    /** Get the text output default charset, used if the output does not
050     * specify a charset.
051     * @return text output default charset
052     */
053    public Charset getDefaultCharset() {
054        return defaultCharset;
055    }
056
057    /** Set the text output default charset, used if the output does not
058     * specify a charset.
059     * @param defaultCharset text output default charset
060     */
061    public void setDefaultCharset(final Charset defaultCharset) {
062        this.defaultCharset = defaultCharset;
063    }
064
065    /** Get the line separator. This value defaults to {@value #DEFAULT_LINE_SEPARATOR}.
066     * @return the current line separator
067     */
068    public String getLineSeparator() {
069        return lineSeparator;
070    }
071
072    /** Set the line separator.
073     * @param lineSeparator the line separator to use
074     */
075    public void setLineSeparator(final String lineSeparator) {
076        this.lineSeparator = lineSeparator;
077    }
078
079    /** Get the double format function used to convert double values
080     * to strings.
081     * @return double format function
082     */
083    public DoubleFunction<String> getDoubleFormat() {
084        return doubleFormat;
085    }
086
087    /** Set the double format function used to convert double values
088     * to strings. The given function must be thread-safe if this handler
089     * is to be used in a multi-threaded context.
090     * @param doubleFormat double format function
091     */
092    public void setDoubleFormat(final DoubleFunction<String> doubleFormat) {
093        this.doubleFormat = doubleFormat;
094    }
095
096    /** {@inheritDoc} */
097    @Override
098    public void write(final Stream<? extends PlaneConvexSubset> boundaries, final GeometryOutput out) {
099        try (TextFacetDefinitionWriter writer = getFacetDefinitionWriter(out)) {
100            final Iterator<? extends PlaneConvexSubset> it = boundaries.iterator();
101            while (it.hasNext()) {
102                writer.write(it.next());
103            }
104        }
105    }
106
107    /** {@inheritDoc} */
108    @Override
109    public void writeFacets(final Stream<? extends FacetDefinition> facets, final GeometryOutput out) {
110        try (TextFacetDefinitionWriter writer = getFacetDefinitionWriter(out)) {
111            final Iterator<? extends FacetDefinition> it = facets.iterator();
112            while (it.hasNext()) {
113                writer.write(it.next());
114            }
115        }
116    }
117
118    /** Get a configured {@link TextFacetDefinitionWriter} for writing output.
119     * @param out output stream to write to
120     * @return a new, configured text format writer
121     * @throws java.io.UncheckedIOException if an I/O error occurs
122     */
123    protected TextFacetDefinitionWriter getFacetDefinitionWriter(final GeometryOutput out) {
124        final TextFacetDefinitionWriter facetWriter =
125                new TextFacetDefinitionWriter(GeometryIOUtils.createBufferedWriter(out, defaultCharset));
126
127        facetWriter.setLineSeparator(lineSeparator);
128        facetWriter.setDoubleFormat(doubleFormat);
129
130        return facetWriter;
131    }
132}