Add MapBodyOrder
[netconf.git] / netconf / netconf-netty-util / src / main / java / org / opendaylight / netconf / nettyutil / handler / exi / EXISchema.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.netconf.nettyutil.handler.exi;
9
10 import static java.util.Objects.requireNonNull;
11
12 import com.google.common.base.Suppliers;
13 import com.google.common.io.ByteSource;
14 import com.google.common.io.Resources;
15 import java.io.IOException;
16 import java.io.InputStream;
17 import java.util.function.Supplier;
18 import org.eclipse.jdt.annotation.Nullable;
19 import org.opendaylight.netconf.shaded.exificient.core.exceptions.EXIException;
20 import org.opendaylight.netconf.shaded.exificient.core.grammars.Grammars;
21 import org.opendaylight.netconf.shaded.exificient.grammars.GrammarFactory;
22
23 /**
24  * Enumeration of schema modes defined by the NETCONF EXI capability.
25  */
26 public enum EXISchema {
27     NONE("none") {
28         @Override
29         Grammars createGrammar() {
30             return GrammarFactory.newInstance().createSchemaLessGrammars();
31         }
32     },
33     BUILTIN("builtin") {
34         @Override
35         Grammars createGrammar() {
36             try {
37                 return GrammarFactory.newInstance().createXSDTypesOnlyGrammars();
38             } catch (EXIException e) {
39                 throw new IllegalStateException("Failed to create builtin grammar", e);
40             }
41         }
42     },
43     BASE_1_1("base:1.1") {
44         @Override
45         Grammars createGrammar() {
46             final ByteSource source = Resources.asByteSource(EXISchema.class.getResource("/rfc6241.xsd"));
47             try (InputStream is = source.openStream()) {
48                 final Grammars g = GrammarFactory.newInstance().createGrammars(is);
49                 g.setSchemaId(getOption());
50                 return g;
51             } catch (EXIException | IOException e) {
52                 throw new IllegalStateException("Failed to create RFC6241 grammar", e);
53             }
54         }
55     };
56
57     private String option;
58     private Supplier<Grammars> grammarsSupplier;
59
60     EXISchema(final String option) {
61         this.option = requireNonNull(option);
62         // Grammar instantiation can be CPU-intensive, hence we instantiate it lazily through a memoizing supplier
63         this.grammarsSupplier = Suppliers.memoize(this::createGrammar);
64     }
65
66     final String getOption() {
67         return option;
68     }
69
70     /**
71      * Return the grammar associated with this EXISchema.
72      *
73      * @return An EXI grammar.
74      */
75     final Grammars getGrammar() {
76         return grammarsSupplier.get();
77     }
78
79     /**
80      * Create grammars associated with this EXISchema. This is a potentially expensive operation for internal use only,
81      * use {@link #getGrammar()} instead.
82      *
83      * @return An EXI grammar.
84      */
85     abstract Grammars createGrammar();
86
87     static @Nullable EXISchema forOption(final String id) {
88         for (EXISchema s : EXISchema.values()) {
89             if (id.equals(s.getOption())) {
90                 return s;
91             }
92         }
93         return null;
94     }
95 }