BUG-4688: Rework SchemaContext module lookups
[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 com.google.common.base.Preconditions;
11 import com.google.common.collect.BiMap;
12 import com.google.common.collect.HashBiMap;
13 import java.io.OutputStream;
14 import java.net.URI;
15 import java.util.Date;
16 import java.util.Map;
17 import javax.xml.stream.XMLOutputFactory;
18 import javax.xml.stream.XMLStreamException;
19 import javax.xml.stream.XMLStreamWriter;
20 import org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil;
21 import org.opendaylight.yangtools.yang.model.api.Module;
22 import org.opendaylight.yangtools.yang.model.api.ModuleImport;
23 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
24
25 public final class YinExportUtils {
26
27     private YinExportUtils() {
28         throw new UnsupportedOperationException("Utility class");
29     }
30
31     /**
32      *
33      * Returns well-formed file name of YIN file as defined in RFC6020.
34      *
35      * @param name
36      *            Module or submodule name
37      * @param revision
38      *            Revision of module or submodule
39      * @return well-formed file name of YIN file as defined in RFC6020.
40      */
41     public static String wellFormedYinName(final String name, final Date revision) {
42         return wellFormedYinName(name, SimpleDateFormatUtil.getRevisionFormat().format(revision));
43     }
44
45     /**
46      *
47      * Returns well-formed file name of YIN file as defined in RFC6020.
48      *
49      * @param name
50      *            name Module or submodule name
51      * @param revision
52      *            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         return String.format("%s@%s.yin", Preconditions.checkNotNull(name), Preconditions.checkNotNull(revision));
57     }
58
59     /**
60      * Writes YIN representation of supplied module to specified output stream.
61      *
62      * @param ctx
63      *            Schema Context which contains module and extension definitions
64      *            to be used during export of model.
65      * @param module
66      *            Module to be exported.
67      * @param str
68      *            Output stream to which YIN representation of model will be
69      *            written.
70      * @throws XMLStreamException
71      */
72     public static void writeModuleToOutputStream(final SchemaContext ctx, final Module module, final OutputStream str)
73             throws XMLStreamException {
74         writeModuleToOutputStream(ctx, module, str, false);
75     }
76
77     /**
78      * Writes YIN representation of supplied module to specified output stream.
79      *
80      * @param ctx
81      *            Schema Context which contains module and extension definitions
82      *            to be used during export of model.
83      * @param module
84      *            Module to be exported.
85      * @param str
86      *            Output stream to which YIN representation of model will be
87      *            written.
88      * @param emitInstantiated
89      *            Option to emit also instantiated statements (e.g. statements
90      *            added by uses or augment)
91      * @throws XMLStreamException
92      */
93     public static void writeModuleToOutputStream(final SchemaContext ctx, final Module module, final OutputStream str,
94             final boolean emitInstantiated) throws XMLStreamException {
95         final XMLOutputFactory factory = XMLOutputFactory.newFactory();
96         final XMLStreamWriter xmlStreamWriter = factory.createXMLStreamWriter(str);
97         writeModuleToOutputStream(ctx, module, xmlStreamWriter, emitInstantiated);
98         xmlStreamWriter.flush();
99     }
100
101     private static void writeModuleToOutputStream(final SchemaContext ctx, final Module module,
102             final XMLStreamWriter xmlStreamWriter, final boolean emitInstantiated) {
103         final URI moduleNs = module.getNamespace();
104         final Map<String, URI> prefixToNs = prefixToNamespace(ctx, module);
105         final StatementTextWriter yinWriter = SingleModuleYinStatementWriter.create(xmlStreamWriter, moduleNs,
106                 prefixToNs);
107         SchemaContextEmitter.writeToStatementWriter(module, ctx, yinWriter, emitInstantiated);
108     }
109
110     private static Map<String, URI> prefixToNamespace(final SchemaContext ctx, final Module module) {
111         final BiMap<String, URI> prefixMap = HashBiMap.create(module.getImports().size() + 1);
112         prefixMap.put(module.getPrefix(), module.getNamespace());
113         for (final ModuleImport imp : module.getImports()) {
114             final String prefix = imp.getPrefix();
115             final URI namespace = getModuleNamespace(ctx, imp.getModuleName());
116             prefixMap.put(prefix, namespace);
117         }
118         return prefixMap;
119     }
120
121     private static URI getModuleNamespace(final SchemaContext ctx, final String moduleName) {
122         for (final Module module : ctx.getModules()) {
123             if (moduleName.equals(module.getName())) {
124                 return module.getNamespace();
125             }
126         }
127         throw new IllegalArgumentException("Module " + moduleName + "does not exists in provided schema context");
128     }
129
130 }