Merge branch 'master' of ../controller
[yangtools.git] / yang / yang-model-export / src / main / java / org / opendaylight / yangtools / yang / model / export / ExportUtils.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 com.google.common.base.Verify.verify;
11
12 import java.util.Map;
13 import java.util.Map.Entry;
14 import java.util.Optional;
15 import org.eclipse.jdt.annotation.NonNull;
16 import org.eclipse.jdt.annotation.Nullable;
17 import org.opendaylight.yangtools.yang.common.QName;
18 import org.opendaylight.yangtools.yang.common.QNameModule;
19 import org.opendaylight.yangtools.yang.common.Revision;
20 import org.opendaylight.yangtools.yang.common.YangConstants;
21
22 /**
23  * Internal shared helpers.
24  * @author Robert Varga
25  *
26  */
27 final class ExportUtils {
28     private ExportUtils() {
29         // Hidden on purpose
30     }
31
32     static Optional<String> statementPrefix(final Map<QNameModule, String> namespaces, final QName stmtName) {
33         final QNameModule namespace = stmtName.getModule();
34         if (YangConstants.RFC6020_YIN_MODULE.equals(namespace)) {
35             return Optional.empty();
36         }
37
38         // Non-default namespace, a prefix is needed
39         @Nullable String prefix = namespaces.get(namespace);
40         if (prefix == null && !namespace.getRevision().isPresent()) {
41             // FIXME: this is an artifact of commonly-bound statements in parser, which means a statement's name
42             //        does not have a Revision. We'll need to find a solution to this which is acceptable. There
43             //        are multiple ways of fixing this:
44             //        - perhaps EffectiveModuleStatement should be giving us a statement-to-EffectiveModule map?
45             //        - or DeclaredStatement should provide the prefix?
46             //        The second one seems cleaner, as that means we would not have perform any lookup at all...
47             Entry<QNameModule, @NonNull String> match = null;
48             for (Entry<QNameModule, @NonNull String> entry : namespaces.entrySet()) {
49                 final QNameModule ns = entry.getKey();
50                 if (namespace.equals(ns.withoutRevision()) && (match == null
51                         || Revision.compare(match.getKey().getRevision(), ns.getRevision()) < 0)) {
52                     match = entry;
53                 }
54             }
55
56             if (match != null) {
57                 prefix = match.getValue();
58             }
59         }
60
61         if (prefix == null) {
62             throw new IllegalArgumentException("Failed to find prefix for statement " + stmtName);
63         }
64
65         verify(!prefix.isEmpty(), "Empty prefix for statement %s", stmtName);
66         return Optional.of(prefix);
67     }
68 }