Merge branch 'master' of ../controller
[yangtools.git] / yang / yang-model-export / src / main / java / org / opendaylight / yangtools / yang / model / export / YangTextSnippet.java
1 /*
2  * Copyright (c) 2018 Pantheon Technologies, s.r.o. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.yangtools.yang.model.export;
9
10 import static java.util.Objects.requireNonNull;
11 import static org.eclipse.jdt.annotation.DefaultLocation.PARAMETER;
12 import static org.eclipse.jdt.annotation.DefaultLocation.RETURN_TYPE;
13
14 import com.google.common.annotations.Beta;
15 import java.util.Iterator;
16 import java.util.Map;
17 import java.util.Set;
18 import java.util.Spliterator;
19 import java.util.Spliterators;
20 import java.util.stream.Collectors;
21 import java.util.stream.Stream;
22 import java.util.stream.StreamSupport;
23 import org.eclipse.jdt.annotation.NonNull;
24 import org.eclipse.jdt.annotation.NonNullByDefault;
25 import org.opendaylight.yangtools.concepts.Immutable;
26 import org.opendaylight.yangtools.yang.common.QNameModule;
27 import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
28 import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
29
30 /**
31  * A YANG text snippet generated from a {@link DeclaredStatement}. Generated {@link #stream()} or {@link #iterator()}
32  * are guaranteed to not contain null nor empty strings. Furthermore, newlines are always emitted at the end
33  * on the generated string -- which can be checked with {@link #isEolString(String)} utility method.
34  *
35  * <p>
36  * This allows individual strings to be escaped as needed and external indentation can be accounted for by inserting
37  * outer document indentation after the string which matched {@link #isEolString(String)} is emitted to the stream.
38  *
39  * @author Robert Varga
40  */
41 @Beta
42 @NonNullByDefault({ PARAMETER, RETURN_TYPE })
43 public final class YangTextSnippet implements Immutable, Iterable<@NonNull String> {
44     private final Set<@NonNull StatementDefinition> ignoredStatements;
45     private final Map<QNameModule, @NonNull String> mapper;
46     private final DeclaredStatement<?> statement;
47     private final boolean omitDefaultStatements;
48
49     YangTextSnippet(final DeclaredStatement<?> statement, final Map<QNameModule, @NonNull String> namespaces,
50             final Set<@NonNull StatementDefinition> ignoredStatements, final boolean omitDefaultStatements) {
51         this.statement = requireNonNull(statement);
52         this.mapper = requireNonNull(namespaces);
53         this.ignoredStatements = requireNonNull(ignoredStatements);
54         this.omitDefaultStatements = omitDefaultStatements;
55     }
56
57     @Override
58     public Iterator<@NonNull String> iterator() {
59         return new YangTextSnippetIterator(statement, mapper, ignoredStatements, omitDefaultStatements);
60     }
61
62     @Override
63     @SuppressWarnings("null")
64     public Spliterator<@NonNull String> spliterator() {
65         return Spliterators.spliteratorUnknownSize(iterator(),
66             Spliterator.ORDERED | Spliterator.IMMUTABLE | Spliterator.NONNULL);
67     }
68
69     @SuppressWarnings("null")
70     public Stream<@NonNull String> stream() {
71         return StreamSupport.stream(spliterator(), false);
72     }
73
74     /**
75      * Check if an emitted string contains End-Of-Line character.
76      *
77      * @param str String to be checked
78      * @return True if the string contains end of line.
79      * @throws NullPointerException if str is null
80      */
81     public static boolean isEolString(final String str) {
82         return !str.isEmpty() && str.charAt(str.length() - 1) == '\n';
83     }
84
85     @Override
86     @SuppressWarnings("null")
87     public String toString() {
88         return stream().collect(Collectors.joining());
89     }
90 }