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