084b161649fc703e66efd77e44371806c3f526c2
[yangtools.git] / yang / yang-model-export / src / main / java / org / opendaylight / yangtools / yang / model / export / YinExportUtils.java
1 /*
2  * Copyright (c) 2015 Cisco Systems, Inc. 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 com.google.common.base.Preconditions.checkArgument;
11 import static java.util.Objects.requireNonNull;
12
13 import com.google.common.annotations.Beta;
14 import java.io.OutputStream;
15 import java.util.Optional;
16 import javax.xml.stream.XMLEventReader;
17 import javax.xml.stream.XMLStreamException;
18 import javax.xml.transform.OutputKeys;
19 import javax.xml.transform.Transformer;
20 import javax.xml.transform.TransformerException;
21 import javax.xml.transform.TransformerFactory;
22 import javax.xml.transform.stax.StAXSource;
23 import javax.xml.transform.stream.StreamResult;
24 import org.opendaylight.yangtools.yang.common.Revision;
25 import org.opendaylight.yangtools.yang.common.YangConstants;
26 import org.opendaylight.yangtools.yang.model.api.Module;
27 import org.opendaylight.yangtools.yang.model.api.stmt.ModuleEffectiveStatement;
28 import org.opendaylight.yangtools.yang.model.api.stmt.SubmoduleEffectiveStatement;
29
30 public final class YinExportUtils {
31     private static final TransformerFactory TRANSFORMER_FACTORY = TransformerFactory.newInstance();
32
33     private YinExportUtils() {
34         // Hidden on purpose
35     }
36
37     /**
38      * Returns well-formed file name of YIN file as defined in RFC6020.
39      *
40      * @param name Module or submodule name
41      * @param revision Revision of module or submodule
42      * @return well-formed file name of YIN file as defined in RFC6020.
43      */
44     public static String wellFormedYinName(final String name, final Optional<Revision> revision) {
45         return wellFormedYinName(name, revision.map(Revision::toString).orElse(null));
46     }
47
48     /**
49      * Returns well-formed file name of YIN file as defined in RFC6020.
50      *
51      * @param name name Module or submodule name
52      * @param revision Revision of module or submodule
53      * @return well-formed file name of YIN file as defined in RFC6020.
54      */
55     public static String wellFormedYinName(final String name, final String revision) {
56         if (revision == null) {
57             return name + YangConstants.RFC6020_YIN_FILE_EXTENSION;
58         }
59         return requireNonNull(name) + '@' + revision +  YangConstants.RFC6020_YIN_FILE_EXTENSION;
60     }
61
62     /**
63      * Write a module as a YIN text into specified {@link OutputStream}. Supplied module must have the
64      * {@link ModuleEffectiveStatement} trait.
65      *
66      * @param module Module to be exported
67      * @throws IllegalArgumentException if the module is not an ModuleEffectiveStatement or if it declared
68      *                                  representation is not available.
69      * @throws NullPointerException if any of of the parameters is null
70      * @throws XMLStreamException if an input-output error occurs
71      * @deprecated Prefer {@link #writeModuleAsYinText(ModuleEffectiveStatement, OutputStream)}.
72      */
73     @Beta
74     @Deprecated
75     public static void writeModuleAsYinText(final Module module, final OutputStream output) throws XMLStreamException {
76         requireNonNull(module);
77         checkArgument(module instanceof ModuleEffectiveStatement, "Module %s is not a ModuleEffectiveStatement",
78             module);
79         writeModuleAsYinText((ModuleEffectiveStatement) module, output);
80     }
81
82     /**
83      * Write a module as a YIN text into specified {@link OutputStream}. Supplied module must have the
84      * {@link ModuleEffectiveStatement} trait.
85      *
86      * @param module Module to be exported
87      * @throws IllegalArgumentException if the module's declared representation is not available.
88      * @throws NullPointerException if any of of the parameters is null
89      * @throws XMLStreamException if an input-output error occurs
90      */
91     @Beta
92     public static void writeModuleAsYinText(final ModuleEffectiveStatement module, final OutputStream output)
93             throws XMLStreamException {
94         writeReaderToOutput(YinXMLEventReaderFactory.defaultInstance().createXMLEventReader(module), output);
95     }
96
97     /**
98      * Write a submodule as a YIN text into specified {@link OutputStream}. Supplied submodule must have the
99      * {@link SubmoduleEffectiveStatement} trait.
100      *
101      * @param parentModule Parent module
102      * @param submodule Submodule to be exported
103      * @throws IllegalArgumentException if the parent module is not a ModuleEffectiveStatement, if the submodule is not
104      *                                  a SubmoduleEffectiveStatement or if its declared representation is not available
105      * @throws NullPointerException if any of of the parameters is null
106      * @throws XMLStreamException if an input-output error occurs
107      * @deprecated Prefer {@link #writeSubmoduleAsYinText(ModuleEffectiveStatement, SubmoduleEffectiveStatement,
108      *             OutputStream)}.
109      */
110     @Beta
111     @Deprecated
112     public static void writeSubmoduleAsYinText(final Module parentModule, final Module submodule,
113             final OutputStream output) throws XMLStreamException {
114         requireNonNull(parentModule);
115         checkArgument(parentModule instanceof ModuleEffectiveStatement, "Parent %s is not a ModuleEffectiveStatement",
116             parentModule);
117         requireNonNull(submodule);
118         checkArgument(submodule instanceof SubmoduleEffectiveStatement,
119             "Submodule %s is not a SubmoduleEffectiveStatement", submodule);
120         writeSubmoduleAsYinText((ModuleEffectiveStatement) parentModule, (SubmoduleEffectiveStatement)submodule,
121             output);
122     }
123
124     /**
125      * Write a submodule as a YIN text into specified {@link OutputStream}. Supplied submodule must have the
126      * {@link SubmoduleEffectiveStatement} trait.
127      *
128      * @param parentModule Parent module
129      * @param submodule Submodule to be exported
130      * @throws IllegalArgumentException if the parent module's or submodule's declared representation is not available
131      * @throws NullPointerException if any of of the parameters is null
132      * @throws XMLStreamException if an input-output error occurs
133      */
134     @Beta
135     public static void writeSubmoduleAsYinText(final ModuleEffectiveStatement parentModule,
136             final SubmoduleEffectiveStatement submodule, final OutputStream output) throws XMLStreamException {
137         writeReaderToOutput(YinXMLEventReaderFactory.defaultInstance().createXMLEventReader(parentModule, submodule),
138             output);
139     }
140
141     private static void writeReaderToOutput(final XMLEventReader reader, final OutputStream output)
142             throws XMLStreamException {
143         try {
144             final Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
145             transformer.setOutputProperty(OutputKeys.INDENT, "yes");
146             transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
147             transformer.transform(new StAXSource(reader), new StreamResult(output));
148         } catch (TransformerException e) {
149             throw new XMLStreamException("Failed to stream XML events", e);
150         }
151     }
152 }