<?xml version="1.0" encoding="UTF-8"?>
+<!-- vi: set et smarttab sw=4 tabstop=4: -->
+<!--
+ Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ and is available at http://www.eclipse.org/legal/epl-v10.html
+-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <parent>
+ <parent>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>yangtools-parent</artifactId>
<version>0.7.0-SNAPSHOT</version>
<relativePath>../common/parent</relativePath>
- </parent>
- <modelVersion>4.0.0</modelVersion>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>benchmarks</artifactId>
+ <artifactId>benchmarks</artifactId>
- <properties>
- <yangtools.version>0.7.0-SNAPSHOT</yangtools.version>
- <yang.maven.plugin.version>0.7.0-SNAPSHOT</yang.maven.plugin.version>
- <java.source.version>1.7</java.source.version>
- <java.target.version>1.7</java.target.version>
- <jmh.version>0.9.7</jmh.version>
- </properties>
+ <properties>
+ <yangtools.version>0.7.0-SNAPSHOT</yangtools.version>
+ <yang.maven.plugin.version>0.7.0-SNAPSHOT</yang.maven.plugin.version>
+ <java.source.version>1.7</java.source.version>
+ <java.target.version>1.7</java.target.version>
+ <jmh.version>0.9.7</jmh.version>
+ </properties>
- <dependencies>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>yang-data-impl</artifactId>
- <version>${yangtools.version}</version>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>yang-parser-impl</artifactId>
- <version>${yangtools.version}</version>
- </dependency>
- <dependency>
- <groupId>org.openjdk.jmh</groupId>
- <artifactId>jmh-core</artifactId>
- <version>${jmh.version}</version>
- </dependency>
- <dependency>
- <groupId>org.openjdk.jmh</groupId>
- <artifactId>jmh-generator-annprocess</artifactId>
- <version>${jmh.version}</version>
- </dependency>
- </dependencies>
+ <dependencies>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>yang-data-impl</artifactId>
+ <version>${yangtools.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>yang-parser-impl</artifactId>
+ <version>${yangtools.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.openjdk.jmh</groupId>
+ <artifactId>jmh-core</artifactId>
+ <version>${jmh.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.openjdk.jmh</groupId>
+ <artifactId>jmh-generator-annprocess</artifactId>
+ <version>${jmh.version}</version>
+ </dependency>
+ </dependencies>
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-compiler-plugin</artifactId>
- <configuration>
- <source>${java.source.version}</source>
- <target>${java.source.version}</target>
- </configuration>
- </plugin>
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>exec-maven-plugin</artifactId>
- <configuration>
- <classpathScope>test</classpathScope>
- <executable>java</executable>
- <arguments>
- <argument>-classpath</argument>
- <classpath/>
- <argument>org.openjdk.jmh.Main</argument>
- <argument>.*</argument>
- </arguments>
- </configuration>
- <executions>
- <execution>
- <id>run-benchmarks</id>
- <phase>integration-test</phase>
- <goals>
- <goal>exec</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
- </plugins>
- </build>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <source>${java.source.version}</source>
+ <target>${java.source.version}</target>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>exec-maven-plugin</artifactId>
+ <configuration>
+ <classpathScope>test</classpathScope>
+ <executable>java</executable>
+ <arguments>
+ <argument>-classpath</argument>
+ <classpath/>
+ <argument>org.openjdk.jmh.Main</argument>
+ <argument>.*</argument>
+ </arguments>
+ </configuration>
+ <executions>
+ <execution>
+ <id>run-benchmarks</id>
+ <phase>integration-test</phase>
+ <goals>
+ <goal>exec</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
</project>
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
+import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSortedMap;
-import java.lang.reflect.Constructor;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodHandles.Lookup;
+import java.lang.invoke.MethodType;
import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Collection;
abstract class DataObjectCodecContext<T extends DataNodeContainer> extends DataContainerCodecContext<T> {
private static final Logger LOG = LoggerFactory.getLogger(DataObjectCodecContext.class);
- private static final Class<?>[] CONSTRUCTOR_ARGS = new Class[] { InvocationHandler.class };
+ private static final Lookup LOOKUP = MethodHandles.publicLookup();
+ private static final MethodType CONSTRUCTOR_TYPE = MethodType.methodType(void.class, InvocationHandler.class);
+ private static final MethodType DATAOBJECT_TYPE = MethodType.methodType(DataObject.class, InvocationHandler.class);
private static final Comparator<Method> METHOD_BY_ALPHABET = new Comparator<Method>() {
@Override
public int compare(final Method o1, final Method o2) {
private final ImmutableSortedMap<Method, NodeContextSupplier> byMethod;
private final ImmutableMap<Class<?>, DataContainerCodecPrototype<?>> byStreamClass;
private final ImmutableMap<Class<?>, DataContainerCodecPrototype<?>> byBindingArgClass;
- private final Constructor<?> proxyConstructor;
+ private final MethodHandle proxyConstructor;
// FIXME: this field seems to be unused
private final Method augmentationGetter;
final Class<?> proxyClass = Proxy.getProxyClass(bindingClass().getClassLoader(), new Class[] { bindingClass() });
try {
- proxyConstructor = proxyClass.getConstructor(CONSTRUCTOR_ARGS);
- } catch (NoSuchMethodException | SecurityException e) {
- throw new IllegalStateException("Failed to find constructor");
+ proxyConstructor = LOOKUP.findConstructor(proxyClass, CONSTRUCTOR_TYPE).asType(DATAOBJECT_TYPE);
+ } catch (NoSuchMethodException | IllegalAccessException e) {
+ throw new IllegalStateException("Failed to find contructor for class " + proxyClass);
}
}
protected final DataObject createBindingProxy(final NormalizedNodeContainer<?, ?, ?> node) {
try {
- return (DataObject) proxyConstructor.newInstance(new Object[] { new LazyDataObject(this, node) });
- } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
- throw new IllegalStateException("Failed to construct proxy for " + node, e);
+ return (DataObject) proxyConstructor.invokeExact((InvocationHandler)new LazyDataObject(this, node));
+ } catch (Throwable e) {
+ throw Throwables.propagate(e);
}
}
*/
package org.opendaylight.yangtools.binding.data.codec.impl;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Throwables;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodHandles.Lookup;
+import java.lang.invoke.MethodType;
import java.lang.reflect.Method;
import java.util.concurrent.Callable;
import org.opendaylight.yangtools.binding.data.codec.impl.ValueTypeCodec.SchemaUnawareCodec;
* types, which are same as in NormalizedNode model.
*
*/
-class EncapsulatedValueCodec extends ReflectionBasedCodec implements SchemaUnawareCodec {
+final class EncapsulatedValueCodec extends ReflectionBasedCodec implements SchemaUnawareCodec {
+ private static final Lookup LOOKUP = MethodHandles.publicLookup();
+ private static final MethodType OBJ_METHOD = MethodType.methodType(Object.class, Object.class);
+ private final MethodHandle constructor;
+ private final MethodHandle getter;
- private final Method getter;
- private final Constructor<?> constructor;
-
- EncapsulatedValueCodec(final Class<?> typeClz) {
+ private EncapsulatedValueCodec(final Class<?> typeClz, final MethodHandle constructor, final MethodHandle getter) {
super(typeClz);
- try {
- this.getter = typeClz.getMethod("getValue");
- this.constructor = typeClz.getConstructor(getter.getReturnType());
- } catch (NoSuchMethodException | SecurityException e) {
- throw new IllegalStateException("Could not resolve required method.", e);
- }
+ this.constructor = Preconditions.checkNotNull(constructor);
+ this.getter = Preconditions.checkNotNull(getter);
}
static Callable<EncapsulatedValueCodec> loader(final Class<?> typeClz) {
return new Callable<EncapsulatedValueCodec>() {
@Override
public EncapsulatedValueCodec call() throws Exception {
- return new EncapsulatedValueCodec(typeClz);
+ final Method m = typeClz.getMethod("getValue");
+ final MethodHandle getter = LOOKUP.unreflect(m).asType(OBJ_METHOD);
+ final MethodHandle constructor = LOOKUP.findConstructor(typeClz, MethodType.methodType(void.class, m.getReturnType())).asType(OBJ_METHOD);
+ return new EncapsulatedValueCodec(typeClz, constructor, getter);
}
};
}
@Override
public Object deserialize(final Object input) {
try {
- return constructor.newInstance(input);
- } catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
- throw new IllegalStateException(e);
+ return constructor.invokeExact(input);
+ } catch (Throwable e) {
+ throw Throwables.propagate(e);
}
}
@Override
public Object serialize(final Object input) {
try {
- return getter.invoke(input);
- } catch (IllegalAccessException | InvocationTargetException e) {
- throw new IllegalStateException(e);
+ return getter.invokeExact(input);
+ } catch (Throwable e) {
+ throw Throwables.propagate(e);
}
}
}
\ No newline at end of file
import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition;
import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition.EnumPair;
-class EnumerationCodec extends ReflectionBasedCodec implements SchemaUnawareCodec {
+final class EnumerationCodec extends ReflectionBasedCodec implements SchemaUnawareCodec {
- ImmutableBiMap<String, Enum<?>> yangValueToBinding;
+ private final ImmutableBiMap<String, Enum<?>> yangValueToBinding;
public EnumerationCodec(final Class<? extends Enum<?>> enumeration, final Map<String, Enum<?>> schema) {
super(enumeration);
yangValueToBinding = ImmutableBiMap.copyOf(schema);
}
-
static Callable<EnumerationCodec> loader(final Class<?> returnType,
final EnumTypeDefinition enumSchema) {
Preconditions.checkArgument(Enum.class.isAssignableFrom(returnType));
};
}
-
@Override
public Object deserialize(final Object input) {
Enum<?> value = yangValueToBinding.get(input);
*/
package org.opendaylight.yangtools.binding.data.codec.impl;
+import com.google.common.base.Throwables;
+import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodHandles.Lookup;
import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
-import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
import java.util.LinkedHashMap;
+import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.opendaylight.yangtools.concepts.Codec;
import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
final class IdentifiableItemCodec implements Codec<NodeIdentifierWithPredicates, IdentifiableItem<?, ?>> {
+ private static final Comparator<QName> KEYARG_COMPARATOR = new Comparator<QName>() {
+ @Override
+ public int compare(final QName q1, final QName q2) {
+ return q1.getLocalName().compareToIgnoreCase(q2.getLocalName());
+ }
+ };
+ private static final Lookup LOOKUP = MethodHandles.publicLookup();
private final Map<QName, ValueContext> keyValueContexts;
+ private final List<QName> keysInBindingOrder;
private final ListSchemaNode schema;
- private final Constructor<? extends Identifier<?>> constructor;
private final Class<?> identifiable;
+ private final MethodHandle ctorInvoker;
+ private final MethodHandle ctor;
public IdentifiableItemCodec(final ListSchemaNode schema, final Class<? extends Identifier<?>> keyClass,
final Class<?> identifiable, final Map<QName, ValueContext> keyValueContexts) {
this.schema = schema;
this.identifiable = identifiable;
- this.constructor = getConstructor(keyClass);
+
+ try {
+ ctor = LOOKUP.unreflectConstructor(getConstructor(keyClass));
+ } catch (IllegalAccessException e) {
+ throw new IllegalArgumentException("Missing construct in class " + keyClass);
+ }
+ final MethodHandle inv = MethodHandles.spreadInvoker(ctor.type(), 0);
+ this.ctorInvoker = inv.asType(inv.type().changeReturnType(Identifier.class));
/*
* We need to re-index to make sure we instantiate nodes in the order in which
keys.put(qname, keyValueContexts.get(qname));
}
this.keyValueContexts = ImmutableMap.copyOf(keys);
+
+ /*
+ * When instantiating binding objects we need to specify constructor arguments
+ * in alphabetic order. We play a couple of tricks here to optimize CPU/memory
+ * trade-offs.
+ *
+ * We do not have to perform a sort if the source collection has less than two
+ * elements.
+
+ * We always perform an ImmutableList.copyOf(), as that will turn into a no-op
+ * if the source is already immutable. It will also produce optimized implementations
+ * for empty and singleton collections.
+ *
+ * BUG-2755: remove this if order is made declaration-order-dependent
+ */
+ final List<QName> unsortedKeys = schema.getKeyDefinition();
+ final List<QName> sortedKeys;
+ if (unsortedKeys.size() > 1) {
+ final List<QName> tmp = new ArrayList<>(unsortedKeys);
+ Collections.sort(tmp, KEYARG_COMPARATOR);
+ sortedKeys = tmp;
+ } else {
+ sortedKeys = unsortedKeys;
+ }
+
+ this.keysInBindingOrder = ImmutableList.copyOf(sortedKeys);
}
@Override
public IdentifiableItem<?, ?> deserialize(final NodeIdentifierWithPredicates input) {
- final Collection<QName> keys = schema.getKeyDefinition();
- final ArrayList<Object> bindingValues = new ArrayList<>(keys.size());
- for (final QName key : keys) {
+ final Object[] bindingValues = new Object[keysInBindingOrder.size()];
+ int offset = 0;
+
+ for (final QName key : keysInBindingOrder) {
final Object yangValue = input.getKeyValues().get(key);
- bindingValues.add(keyValueContexts.get(key).deserialize(yangValue));
+ bindingValues[offset++] = keyValueContexts.get(key).deserialize(yangValue);
}
final Identifier<?> identifier;
try {
- identifier = constructor.newInstance(bindingValues.toArray());
- } catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
- throw new IllegalStateException(String.format("Failed to instantiate key class %s", constructor.getDeclaringClass()), e);
+ identifier = (Identifier<?>) ctorInvoker.invokeExact(ctor, bindingValues);
+ } catch (Throwable e) {
+ throw Throwables.propagate(e);
}
@SuppressWarnings({ "rawtypes", "unchecked" })
*/
package org.opendaylight.yangtools.binding.data.codec.impl;
-import com.google.common.base.Objects.ToStringHelper;
+import com.google.common.base.MoreObjects;
+import com.google.common.base.MoreObjects.ToStringHelper;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableMap;
}
public String bindingToString() {
- final ToStringHelper helper = com.google.common.base.Objects.toStringHelper(context.bindingClass()).omitNullValues();
+ final ToStringHelper helper = MoreObjects.toStringHelper(context.bindingClass()).omitNullValues();
for (final Method m :context.getHashCodeAndEqualsMethods()) {
helper.add(m.getName(), getBindingData(m));
package org.opendaylight.yangtools.binding.data.codec.impl;
import com.google.common.collect.ImmutableSet;
-
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.Callable;
-
import org.opendaylight.yangtools.concepts.Codec;
import org.opendaylight.yangtools.yang.binding.BindingMapping;
import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
final class UnionTypeCodec extends ReflectionBasedCodec {
- private Constructor<?> charConstructor;
- private ImmutableSet<UnionValueOptionContext> typeCodecs;
+ private final ImmutableSet<UnionValueOptionContext> typeCodecs;
+ private final Constructor<?> charConstructor;
private UnionTypeCodec(final Class<?> unionCls,final Set<UnionValueOptionContext> codecs) {
super(unionCls);
}
}
- static final Callable<UnionTypeCodec> loader(final Class<?> unionCls, final UnionTypeDefinition unionType) {
+ static Callable<UnionTypeCodec> loader(final Class<?> unionCls, final UnionTypeDefinition unionType) {
return new Callable<UnionTypeCodec>() {
@Override
public UnionTypeCodec call() throws NoSuchMethodException, SecurityException {
};
}
- private static Codec<Object, Object> getCodecForType(Class valueType, TypeDefinition subtype) {
+ private static Codec<Object, Object> getCodecForType(final Class<?> valueType, final TypeDefinition<?> subtype) {
if (subtype.getBaseType() instanceof UnionType) {
try {
return UnionTypeCodec.loader(valueType, (UnionType) subtype.getBaseType()).call();
@Override
public Object serialize(final Object input) {
- if(input != null) {
- for(UnionValueOptionContext valCtx : typeCodecs) {
+ if (input != null) {
+ for (UnionValueOptionContext valCtx : typeCodecs) {
Object domValue = valCtx.serialize(input);
- if(domValue != null) {
+ if (domValue != null) {
return domValue;
}
}
*/
package org.opendaylight.yangtools.binding.data.codec.impl;
-import java.lang.reflect.InvocationTargetException;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Throwables;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodHandles.Lookup;
+import java.lang.invoke.MethodType;
import java.lang.reflect.Method;
import org.opendaylight.yangtools.concepts.Codec;
final class UnionValueOptionContext {
+ private static final Lookup LOOKUP = MethodHandles.publicLookup();
+ private static final MethodType OBJECT_TYPE = MethodType.methodType(Object.class, Object.class);
+ private final Class<?> bindingType;
+ // FIXME: migrate to invocation
+ private final MethodHandle getter;
+ private final Codec<Object,Object> codec;
- final Method getter;
- final Class<?> bindingType;
- final Codec<Object,Object> codec;
+ UnionValueOptionContext(final Class<?> valueType, final Method getter, final Codec<Object, Object> codec) {
+ this.bindingType = Preconditions.checkNotNull(valueType);
+ this.codec = Preconditions.checkNotNull(codec);
- UnionValueOptionContext(final Class<?> valueType,final Method getter, final Codec<Object, Object> codec) {
- this.getter = getter;
- this.bindingType = valueType;
- this.codec = codec;
+ try {
+ this.getter = LOOKUP.unreflect(getter).asType(OBJECT_TYPE);
+ } catch (IllegalAccessException e) {
+ throw new IllegalStateException("Failed to access method " + getter, e);
+ }
}
- public Object serialize(final Object input) {
- Object baValue = getValueFrom(input);
- if(baValue != null) {
- return codec.serialize(baValue);
+ Object serialize(final Object input) {
+ final Object baValue = getValueFrom(input);
+ if (baValue == null) {
+ return null;
}
- return null;
+
+ return codec.serialize(baValue);
}
- public Object getValueFrom(final Object input) {
+ Object getValueFrom(final Object input) {
try {
- return getter.invoke(input);
- } catch (IllegalAccessException | InvocationTargetException e) {
- throw new IllegalStateException(e);
+ return getter.invokeExact(input);
+ } catch (Throwable e) {
+ throw Throwables.propagate(e);
}
}
if (this == obj) {
return true;
}
- if (obj == null) {
+ if (!(obj instanceof UnionValueOptionContext)) {
return false;
}
- if (getClass() != obj.getClass()) {
- return false;
- }
- UnionValueOptionContext other = (UnionValueOptionContext) obj;
+
+ final UnionValueOptionContext other = (UnionValueOptionContext) obj;
return bindingType.equals(other.bindingType);
}
}
\ No newline at end of file
package org.opendaylight.yangtools.binding.data.codec.impl;
import com.google.common.base.Preconditions;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
+import com.google.common.base.Throwables;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodHandles.Lookup;
+import java.lang.invoke.MethodType;
import org.opendaylight.yangtools.concepts.Codec;
import org.opendaylight.yangtools.yang.binding.BindingMapping;
final class ValueContext {
+ private static final Lookup LOOKUP = MethodHandles.publicLookup();
+ private static final MethodType OBJECT_METHOD = MethodType.methodType(Object.class, Object.class);
private final Codec<Object, Object> codec;
- private final Method getter;
+ private final MethodHandle getter;
+ private final Class<?> identifier;
+ private final String getterName;
ValueContext(final Class<?> identifier, final LeafNodeCodecContext leaf) {
- final String getterName = BindingCodecContext.GETTER_PREFIX
- + BindingMapping.getClassName(leaf.getDomPathArgument().getNodeType());
+ getterName = BindingCodecContext.GETTER_PREFIX + BindingMapping.getClassName(leaf.getDomPathArgument().getNodeType());
try {
- getter = identifier.getMethod(getterName);
- } catch (NoSuchMethodException | SecurityException e) {
- throw new IllegalStateException(e);
+ getter = LOOKUP.unreflect(identifier.getMethod(getterName)).asType(OBJECT_METHOD);
+ } catch (IllegalAccessException | NoSuchMethodException | SecurityException e) {
+ throw new IllegalStateException(String.format("Cannot find method %s in class %s", getterName, identifier), e);
}
+ this.identifier = identifier;
codec = leaf.getValueCodec();
}
Object getAndSerialize(final Object obj) {
+ final Object value;
try {
- final Object value = getter.invoke(obj);
- Preconditions.checkArgument(value != null,
- "All keys must be specified for %s. Missing key is %s. Supplied key is %s",
- getter.getDeclaringClass(), getter.getName(), obj);
- return codec.serialize(value);
- } catch (IllegalAccessException | InvocationTargetException e) {
- throw new IllegalArgumentException(e);
+ value = getter.invokeExact(obj);
+ } catch (Throwable e) {
+ throw Throwables.propagate(e);
}
+
+ Preconditions.checkArgument(value != null,
+ "All keys must be specified for %s. Missing key is %s. Supplied key is %s",
+ identifier, getterName, obj);
+ return codec.serialize(value);
}
Object deserialize(final Object obj) {
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
-import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;
public ParametrizedTypeImpl(final Type rawType, final Type[] actTypes) {
super(rawType.getPackageName(), rawType.getName());
this.rawType = rawType;
- this.actualTypes = Arrays.copyOf(actTypes, actTypes.length);
+ this.actualTypes = actTypes.clone();
}
}
</dependency>
<dependency>
<groupId>org.codehaus.plexus</groupId>
- <artifactId>plexus-slf4j-logging</artifactId>
+ <artifactId>plexus-container-default</artifactId>
+ <version>1.5.6</version>
+ <scope>provided</scope>
+ <exclusions>
+ <!-- plexus-build-api pulls in version 1.5.8, while this pulls in 3.0.20.
+ Dependency convergence would break if we did not specify this. -->
+ <exclusion>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-utils</artifactId>
+ </exclusion>
+ </exclusions>
</dependency>
+
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<salGeneratorPath>src/main/yang-gen-sal</salGeneratorPath>
</properties>
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>yangtools-artifacts</artifactId>
+ <version>${yangtools.version}</version>
+ <type>pom</type>
+ <scope>import</scope>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+
<profiles>
<profile>
<activation>
<exists>src/main/yang</exists>
</file>
</activation>
- <dependencyManagement>
- <dependencies>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yangtools-artifacts</artifactId>
- <version>${yangtools.version}</version>
- <type>pom</type>
- <scope>import</scope>
- </dependency>
- </dependencies>
- </dependencyManagement>
<dependencies>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-binding</artifactId>
- </dependency>
+ <dependency>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>yang-binding</artifactId>
+ </dependency>
</dependencies>
<build>
<pluginManagement>
</execution>
</executions>
</plugin>
- <plugin>
- <artifactId>maven-clean-plugin</artifactId>
- <configuration>
- <filesets>
- <fileset>
- <directory>${salGeneratorPath}</directory>
- <includes>
- <include>**</include>
- </includes>
- </fileset>
- </filesets>
- </configuration>
- </plugin>
+ <plugin>
+ <artifactId>maven-clean-plugin</artifactId>
+ <configuration>
+ <filesets>
+ <fileset>
+ <directory>${salGeneratorPath}</directory>
+ <includes>
+ <include>**</include>
+ </includes>
+ </fileset>
+ </filesets>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>build-helper-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>add-yang-sources</id>
+ <phase>generate-sources</phase>
+ <goals>
+ <goal>add-source</goal>
+ </goals>
+ <configuration>
+ <sources>
+ <source>${salGeneratorPath}</source>
+ </sources>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
</plugins>
</pluginManagement>
- <plugins>
- <plugin>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-maven-plugin</artifactId>
- <version>${yangtools.version}</version>
- </plugin>
- </plugins>
+ <plugins>
+ <plugin>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>yang-maven-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>build-helper-maven-plugin</artifactId>
+ </plugin>
+ </plugins>
</build>
</profile>
</profiles>
<groupId>org.sonatype.plexus</groupId>
<artifactId>plexus-build-api</artifactId>
</dependency>
- <dependency>
- <groupId>org.codehaus.plexus</groupId>
- <artifactId>plexus-slf4j-logging</artifactId>
- </dependency>
<dependency>
<groupId>junit</groupId>
import java.util.Map;
import java.util.Set;
-import org.apache.maven.plugin.logging.Log;
import org.apache.maven.project.MavenProject;
import org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil;
import org.opendaylight.yangtools.sal.binding.generator.api.BindingGenerator;
import org.opendaylight.yangtools.yang.binding.YangModelBindingProvider;
import org.opendaylight.yangtools.yang.model.api.Module;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang2sources.spi.BasicCodeGenerator;
import org.opendaylight.yangtools.yang2sources.spi.BuildContextAware;
-import org.opendaylight.yangtools.yang2sources.spi.CodeGenerator;
+import org.opendaylight.yangtools.yang2sources.spi.MavenProjectAware;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sonatype.plexus.build.incremental.BuildContext;
-public final class CodeGeneratorImpl implements CodeGenerator, BuildContextAware {
+public final class CodeGeneratorImpl implements BasicCodeGenerator, BuildContextAware, MavenProjectAware {
+ private static final Logger logger = LoggerFactory.getLogger(CodeGeneratorImpl.class);
private static final String FS = File.separator;
private BuildContext buildContext;
private File projectBaseDir;
private Map<String, String> additionalConfig;
-
- private static final Logger logger = LoggerFactory.getLogger(CodeGeneratorImpl.class);
private MavenProject mavenProject;
private File resourceBaseDir;
mavenProject.addCompileSourceRoot(outputBaseDir.getPath());
}
- @Override
- public void setLog(final Log log) {
- }
-
@Override
public void setAdditionalConfig(final Map<String, String> additionalConfiguration) {
this.additionalConfig = additionalConfiguration;
import java.util.Map;
import java.util.Set;
-import org.apache.maven.plugin.logging.Log;
-import org.apache.maven.project.MavenProject;
import org.opendaylight.yangtools.yang.model.api.Module;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
import org.opendaylight.yangtools.yang.unified.doc.generator.GeneratorImpl;
-import org.opendaylight.yangtools.yang2sources.spi.CodeGenerator;
+import org.opendaylight.yangtools.yang2sources.spi.BasicCodeGenerator;
-public class DocumentationGeneratorImpl extends GeneratorImpl implements CodeGenerator {
+public class DocumentationGeneratorImpl extends GeneratorImpl implements BasicCodeGenerator {
@Override
public Collection<File> generateSources(SchemaContext arg0, File arg1, Set<Module> arg2) throws IOException {
return generate(arg0, arg1, arg2);
}
- @Override
- public void setLog(Log log) {
- // use maven logging if necessary
-
- }
-
@Override
public void setAdditionalConfig(Map<String, String> additionalConfiguration) {
// no additional config utilized
public void setResourceBaseDir(File resourceBaseDir) {
// no resource processing necessary
}
-
- @Override
- public void setMavenProject(MavenProject project) {
- // no additional information needed
- }
}
import java.util.Map;
import java.util.Set;
-import org.apache.maven.plugin.logging.Log;
-import org.apache.maven.project.MavenProject;
import org.opendaylight.yangtools.yang.model.api.Module;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
import org.opendaylight.yangtools.yang.wadl.generator.WadlRestconfGenerator;
-import org.opendaylight.yangtools.yang2sources.spi.CodeGenerator;
+import org.opendaylight.yangtools.yang2sources.spi.BasicCodeGenerator;
-public class WadlGenerator implements CodeGenerator {
+public class WadlGenerator implements BasicCodeGenerator {
@Override
public Collection<File> generateSources(SchemaContext context, File outputDir, Set<Module> currentModules)
final File outputBaseDir;
if (outputDir == null) {
+ // FIXME: this hard-codes the destination
outputBaseDir = new File("target" + File.separator + "generated-sources" + File.separator
+ "maven-sal-api-gen" + File.separator + "wadl");
} else {
return generator.generate(context, currentModules);
}
- @Override
- public void setLog(Log log) {
- // TODO Auto-generated method stub
-
- }
-
@Override
public void setAdditionalConfig(Map<String, String> additionalConfiguration) {
// TODO Auto-generated method stub
// TODO Auto-generated method stub
}
-
- @Override
- public void setMavenProject(MavenProject project) {
- // TODO Auto-generated method stub
-
- }
-
}
import org.opendaylight.yangtools.yang.model.api.Module;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
-import org.opendaylight.yangtools.yang2sources.spi.CodeGenerator;
+import org.opendaylight.yangtools.yang2sources.spi.BasicCodeGenerator;
public class DocGenTest {
public static final String FS = File.separator;
final List<File> sourceFiles = getSourceFiles("/doc-gen");
final Set<Module> modulesToBuild = parser.parseYangModels(sourceFiles);
final SchemaContext context = parser.resolveSchemaContext(modulesToBuild);
- final CodeGenerator generator = new DocumentationGeneratorImpl();
+ final BasicCodeGenerator generator = new DocumentationGeneratorImpl();
Collection<File> generatedFiles = generator.generateSources(context, GENERATOR_OUTPUT_DIR, modulesToBuild);
assertEquals(4, generatedFiles.size());
}
import org.opendaylight.yangtools.yang.model.api.Module;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
-import org.opendaylight.yangtools.yang2sources.spi.CodeGenerator;
+import org.opendaylight.yangtools.yang2sources.spi.BasicCodeGenerator;
public class WadlGenTest {
public static final String FS = File.separator;
final List<File> sourceFiles = getSourceFiles("/wadl-gen");
final Set<Module> modulesToBuild = parser.parseYangModels(sourceFiles);
final SchemaContext context = parser.resolveSchemaContext(modulesToBuild);
- final CodeGenerator generator = new WadlGenerator();
+ final BasicCodeGenerator generator = new WadlGenerator();
Collection<File> generatedWadlFiles = generator.generateSources(context, GENERATOR_OUTPUT_DIR, modulesToBuild);
assertEquals(3, generatedWadlFiles.size());
}
<module>binding-data-codec</module>
<module>binding-parent</module>
</modules>
-
- <build>
- <pluginManagement>
- <plugins>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <version>${maven.bundle.version}</version>
- <extensions>true</extensions>
- <executions>
- <execution>
- <id>bundle-manifest</id>
- <phase>process-classes</phase>
- <goals>
- <goal>manifest</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
- <plugin>
- <groupId>org.eclipse.m2e</groupId>
- <artifactId>lifecycle-mapping</artifactId>
- <version>1.0.0</version>
- <configuration>
- <lifecycleMappingMetadata>
- <pluginExecutions>
- <pluginExecution>
- <pluginExecutionFilter>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <versionRange>[1.0,)</versionRange>
- <goals>
- <goal>manifest</goal>
- </goals>
- </pluginExecutionFilter>
- <action>
- <execute />
- </action>
- </pluginExecution>
- </pluginExecutions>
- </lifecycleMappingMetadata>
- </configuration>
- </plugin>
- </plugins>
- </pluginManagement>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-checkstyle-plugin</artifactId>
- </plugin>
- </plugins>
- </build>
-
</project>
<name>${project.artifactId}</name>
<description>Common concepts</description>
+ <dependencies>
+ <dependency>
+ <groupId>com.google.code.findbugs</groupId>
+ <artifactId>jsr305</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ </dependencies>
+
<build>
<plugins>
<plugin>
*/
package org.opendaylight.yangtools.concepts;
-public interface Path<P extends Path<P>> {
+import javax.annotation.Nonnull;
- boolean contains(P other);
+/**
+ * Conceptual representation of a logical path in a tree-like structure, similar to a
+ * {@link java.nio.file.Path}, but more general in terms of what objects it can be applied to.
+ * Paths have an equivalence class, which is captured in the defining type. Paths also have the
+ * notion of containment, where one path is said to contain another path if it the data set
+ * identified by the former contains all elements of the data set represented by later.
+ *
+ * @param <P> Path equivalence class
+ */
+public interface Path<P extends Path<P>> {
+ /**
+ * Check if this path contains some other.
+ *
+ * @param other Other path, may not be null.
+ * @return True if this path contains the other.
+ */
+ boolean contains(@Nonnull P other);
}
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- vi: set et smarttab sw=4 tabstop=4: -->
-<!--
- Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
-
- This program and the accompanying materials are made available under the
- terms of the Eclipse Public License v1.0 which accompanies this distribution,
- and is available at http://www.eclipse.org/legal/epl-v10.html
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.opendaylight.odlparent</groupId>
- <artifactId>odlparent</artifactId>
- <version>1.5.0-SNAPSHOT</version>
- </parent>
-
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>features-builder</artifactId>
- <packaging>pom</packaging>
- <version>0.7.0-SNAPSHOT</version>
-
- <properties>
- <features.file>features.xml</features.file>
- </properties>
-
- <build>
- <resources>
- <resource>
- <directory>src/main/resources</directory>
- <filtering>true</filtering>
- </resource>
- </resources>
-
- <pluginManagement>
- <plugins>
- <!-- generate dependencies versions -->
- <plugin>
- <artifactId>maven-dependency-plugin</artifactId>
- <executions>
- <execution>
- <phase>generate-resources</phase>
- <goals><goal>resolve</goal></goals>
- <configuration>
- <outputFile>${project.build.directory}/dependencies.txt</outputFile>
- </configuration>
- </execution>
- </executions>
- </plugin>
- <plugin>
- <groupId>com.alexecollins.maven.plugin</groupId>
- <artifactId>script-maven-plugin</artifactId>
- <version>1.0.0</version>
- <executions>
- <execution>
- <id>add-version-to-features</id>
- <phase>generate-resources</phase>
- <goals>
- <goal>execute</goal>
- </goals>
- <configuration>
- <language>groovy</language>
- <script>
- /**
- * Placeholder, which is used in src/feature/features.xml
- * to mark version which should be inserted from dependencies.
- * Currently works only for bundle and configfile tags
- * with mvn: url schema, and needs to be used
- * as third component of schema.
- * eg. mvn:group/artefact/{{VERSION}}
- */
- def versionPlaceholder = "{{VERSION}}"
- /**
- * Path to features.xml which uses versionPlaceholder.
- * This will be processed by this script.
- *
- */
- def featureFilePath = "src/main/feature/features.xml"
- // Contains mapping of groupID:artefactID to versoin
- def versionMap = new HashMap();
- /* Loads transitive dependency list generated from
- * maven-dependency-plugin resolve goal
- * and populates map
- */
- def dependencies = new File(project.build.directory,"dependencies.txt")
- dependencies.eachLine {
- def cmps = it.trim().split(":")
- // 0 - groupId
- // 1 - artifactId
- // 2 - Type
- // 3 - Version
- if(cmps.length >= 4) {
- def id = cmps[0] + ":" + cmps[1]
- versionMap[id] = cmps[3]
- }
- }
-
- /*
- * Takes splitted mvn: URL, looks for placeholder
- * and returns new mvn: URL with version learned
- * from dependency plugin.
- *
- * If referenced bundle is not dependency (direct or transitive)
- * throws an exception and fails build.
- *
- */
- def updatedURLFromProject = { args ->
- // 0 - groupID, 1 - artifactID
- // 2 - version, 3 - type, 4 - Classifier
-
- def groupId = args[0];
- def artifactId = args[1];
- def id = groupId + ":" + artifactId
- def dependencyVersion = versionMap[id]
- if(dependencyVersion != null) {
- // Overriding version
- args[2] = dependencyVersion
- return "mvn:" + args.join("/")
- }
- throw new IllegalArgumentException("Feature dependency $groupId:$artifactId is not dependecy of project.")
- }
-
-
- def updateMavenDependency = { dep ->
- def mvnUrl = dep.text()
- if(mvnUrl.startsWith("mvn:")) {
- def components = mvnUrl.substring(4).split("/")
- if(components[2] == versionPlaceholder) {
- dep.value = updatedURLFromProject(components)
- }
- }
- }
-
- def featureFile = new File(project.basedir,featureFilePath)
- def root = new XmlParser().parse(featureFile)
-
- root.feature.each { feature ->
- println "[INFO] Processing feature: ${feature.@name}"
- feature.bundle.each updateMavenDependency
- feature.configfile.each updateMavenDependency
- }
-
- def outDir = new File(project.build.directory,"generated-resources/script")
- outDir.mkdirs();
- def outFile = new File(outDir,"features.xml")
- def outWriter = outFile.newPrintWriter("ASCII");
- xmlPrinter = new XmlNodePrinter(outWriter);
- xmlPrinter.preserveWhitespace = true
- xmlPrinter.print(root)
- outWriter.close();
- </script>
- </configuration>
- </execution>
- </executions>
- <dependencies>
- <dependency>
- <groupId>org.codehaus.groovy</groupId>
- <artifactId>groovy</artifactId>
- <version>1.8.6</version>
- </dependency>
- </dependencies>
- </plugin>
- <plugin>
- <groupId>org.apache.karaf.tooling</groupId>
- <artifactId>karaf-maven-plugin</artifactId>
- <version>${karaf.version}</version>
- <extensions>true</extensions>
- <executions>
- <execution>
- <id>features-create-kar</id>
- <goals>
- <goal>features-create-kar</goal>
- </goals>
- <configuration>
- <featuresFile>${project.build.directory}/classes/${features.file}</featuresFile>
- </configuration>
- </execution>
- </executions>
- <!-- There is no useful configuration for the kar mojo. The features-generate-descriptor mojo configuration may be useful -->
- </plugin>
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>build-helper-maven-plugin</artifactId>
- <executions>
- <execution>
- <phase>generate-resources</phase>
- <goals><goal>add-resource</goal></goals>
- <configuration>
- <resources>
- <resource>
- <directory>${project.build.directory}/generated-resources/script</directory>
- <filtering>true</filtering>
- </resource>
- </resources>
- </configuration>
- </execution>
- <execution>
- <id>attach-artifacts</id>
- <phase>package</phase>
- <goals>
- <goal>attach-artifact</goal>
- </goals>
- <configuration>
- <artifacts>
- <artifact>
- <file>${project.build.directory}/classes/${features.file}</file>
- <type>xml</type>
- <classifier>features</classifier>
- </artifact>
- </artifacts>
- </configuration>
- </execution>
- </executions>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-resources-plugin</artifactId>
- <executions>
- <execution>
- <id>filter</id>
- <phase>generate-resources</phase>
- <goals>
- <goal>resources</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-surefire-plugin</artifactId>
- <configuration>
- <dependenciesToScan>
- <dependency>org.opendaylight.yangtools:features-test</dependency>
- </dependenciesToScan>
- </configuration>
- </plugin>
- </plugins>
- </pluginManagement>
- </build>
-
- <dependencies>
- <!-- test the features.xml -->
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>features-test</artifactId>
- <version>0.7.0-SNAPSHOT</version>
- <scope>test</scope>
- </dependency>
- </dependencies>
-</project>
<properties>
<pax.exam.version>3.5.0</pax.exam.version>
</properties>
+
+ <!-- Migrated to odlparent -->
+ <distributionManagement>
+ <relocation>
+ <groupId>org.opendaylight.odlparent</groupId>
+ <artifactId>features-test</artifactId>
+ <version>1.5.0-SNAPSHOT</version>
+ <message>This artifact has been migrated to odlparent and will be removed in Lithium release</message>
+ </relocation>
+ </distributionManagement>
+
<dependencies>
<!-- Dependencies for pax exam karaf container -->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>features-builder</artifactId>
- <version>0.7.0-SNAPSHOT</version>
- <relativePath>../features-builder/pom.xml</relativePath>
+ <groupId>org.opendaylight.odlparent</groupId>
+ <artifactId>features-parent</artifactId>
+ <version>1.5.0-SNAPSHOT</version>
+ <relativePath/>
</parent>
+ <groupId>org.opendaylight.yangtools</groupId>
<artifactId>features-yangtools</artifactId>
+ <version>0.7.0-SNAPSHOT</version>
<packaging>jar</packaging>
<build>
<ignore/>
</action>
</pluginExecution>
+ <pluginExecution>
+ <pluginExecutionFilter>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-checkstyle-plugin</artifactId>
+ <versionRange>[2.12,)</versionRange>
+ <goals>
+ <goal>check</goal>
+ </goals>
+ </pluginExecutionFilter>
+ <action>
+ <execute/>
+ </action>
+ </pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
</configuration>
</plugin>
</plugins>
</reporting>
-
-
- <!-- Note: we can not use variables for these URLs because we need to
- be able to download the parent pom from the repository the first
- time we go to use it (since it is in a different project).
- To override the settings, use the "mirror" section of the
- settings.xml. See http://maven.apache.org/settings.html -->
- <repositories>
- <!-- OpenDayLight Repo Mirror -->
- <repository>
- <id>opendaylight-mirror</id>
- <name>opendaylight-mirror</name>
- <url>http://nexus.opendaylight.org/content/groups/public/</url>
- <snapshots>
- <enabled>false</enabled>
- </snapshots>
- <releases>
- <enabled>true</enabled>
- <updatePolicy>never</updatePolicy>
- </releases>
- </repository>
-
- <!-- OpenDayLight Snapshot artifact -->
- <repository>
- <id>opendaylight-snapshot</id>
- <name>opendaylight-snapshot</name>
- <url>http://nexus.opendaylight.org/content/repositories/opendaylight.snapshot/</url>
- <snapshots>
- <enabled>true</enabled>
- </snapshots>
- <releases>
- <enabled>false</enabled>
- </releases>
- </repository>
- </repositories>
</project>
<module>checkstyle-logging</module>
<module>concepts</module>
<module>features</module>
- <module>features-builder</module>
<module>features-test</module>
<module>mockito-configuration</module>
<module>object-cache-api</module>
import javax.annotation.Nullable;
-import com.google.common.base.Objects;
-import com.google.common.base.Objects.ToStringHelper;
+import com.google.common.base.MoreObjects;
+import com.google.common.base.MoreObjects.ToStringHelper;
import com.google.common.base.Preconditions;
import com.google.common.util.concurrent.AbstractListeningExecutorService;
import com.google.common.util.concurrent.ListenableFuture;
@Override
public final String toString(){
- return addToStringAttributes( Objects.toStringHelper( this )
+ return addToStringAttributes( MoreObjects.toStringHelper( this )
.add( "delegate", delegate ) ).toString();
}
}
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
-import com.google.common.base.Objects;
-import com.google.common.base.Objects.ToStringHelper;
+import com.google.common.base.MoreObjects;
+import com.google.common.base.MoreObjects.ToStringHelper;
import com.google.common.base.Preconditions;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
@Override
public final String toString() {
- return addToStringAttributes( Objects.toStringHelper( this )
+ return addToStringAttributes( MoreObjects.toStringHelper( this )
.add( "Thread Prefix", threadPrefix )
.add( "Current Thread Pool Size", getPoolSize() )
.add( "Largest Thread Pool Size", getLargestPoolSize() )
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
-import com.google.common.base.Objects;
-import com.google.common.base.Objects.ToStringHelper;
+import com.google.common.base.MoreObjects;
+import com.google.common.base.MoreObjects.ToStringHelper;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
/**
@Override
public final String toString() {
- return addToStringAttributes( Objects.toStringHelper( this )
+ return addToStringAttributes( MoreObjects.toStringHelper( this )
.add( "Thread Prefix", threadPrefix )
.add( "Current Thread Pool Size", getPoolSize() )
.add( "Largest Thread Pool Size", getLargestPoolSize() )
notifications[i-1] = Integer.valueOf( i );
}
- Stopwatch stopWatch = new Stopwatch();
- stopWatch.start();
+ Stopwatch stopWatch = Stopwatch.createStarted();
List<TestListener<Integer>> listeners = Lists.newArrayList();
for( int i = 1; i <= nListeners; i++ ) {
final ConcurrentMap<Thread, AtomicLong> taskCountPerThread = new ConcurrentHashMap<>();
final AtomicReference<AssertionError> threadError = new AtomicReference<>();
- Stopwatch stopWatch = new Stopwatch();
- stopWatch.start();
+ Stopwatch stopWatch = Stopwatch.createStarted();
new Thread() {
@Override
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
- <dependency>
- <groupId>org.codehaus.plexus</groupId>
- <artifactId>plexus-slf4j-logging</artifactId>
- </dependency>
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yangtools-parent</artifactId>
- <version>0.7.0-SNAPSHOT</version>
- <relativePath>../common/parent</relativePath>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>yangtools-parent</artifactId>
+ <version>0.7.0-SNAPSHOT</version>
+ <relativePath>../common/parent</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<module>regression-test-model</module>
<module>yang-runtime-tests</module>
</modules>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-checkstyle-plugin</artifactId>
- </plugin>
- </plugins>
- </build>
</project>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- vi: set et smarttab sw=4 tabstop=4: -->
-<!--
- Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
-
- This program and the accompanying materials are made available under the
- terms of the Eclipse Public License v1.0 which accompanies this distribution,
- and is available at http://www.eclipse.org/legal/epl-v10.html
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-
- <parent>
- <artifactId>model-ietf</artifactId>
- <groupId>org.opendaylight.yangtools.model</groupId>
- <version>0.7.0-SNAPSHOT</version>
- </parent>
-
- <modelVersion>4.0.0</modelVersion>
- <artifactId>ietf-netconf</artifactId>
- <version>1.0-SNAPSHOT</version>
- <name>${project.artifactId}</name>
- <description>${project.artifactId}</description>
-
- <packaging>bundle</packaging>
-
- <dependencies>
- <dependency>
- <groupId>org.opendaylight.yangtools.model</groupId>
- <artifactId>ietf-inet-types</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools.model</groupId>
- <artifactId>ietf-yang-types</artifactId>
- </dependency>
- </dependencies>
-</project>
to provide room for augmentations, e.g. for
statistics or priorization information associated with
supporting nodes.";
- key "node-ref";
+ // This is not what was published in the initial draft,
+ // added topology-ref leaf and added it to the key
+ key "topology-ref node-ref";
+ leaf topology-ref {
+ type topology-ref;
+ }
leaf node-ref {
type node-ref;
}
<module>ietf-topology-l3-unicast-igp</module>
<module>ietf-topology-ospf</module>
<module>ietf-restconf</module>
- <!--module>ietf-netconf</module -->
</modules>
</project>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
- <version>2.12</version>
<configuration>
<failOnViolation>false</failOnViolation>
<configLocation>checkstyle-logging.xml</configLocation>
<module>yang-model-util</module>
<module>yang-parser-api</module>
<module>yang-parser-impl</module>
+ <module>yang-model-export</module>
<module>yang-data-composite-node</module>
</modules>
<build>
*/
package org.opendaylight.yangtools.yang.binding;
-import com.google.common.base.Objects;
-import com.google.common.base.Objects.ToStringHelper;
+import com.google.common.base.MoreObjects;
+import com.google.common.base.MoreObjects.ToStringHelper;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableCollection;
import com.google.common.collect.ImmutableList;
@Override
public final String toString() {
- return addToStringAttributes(Objects.toStringHelper(this)).toString();
+ return addToStringAttributes(MoreObjects.toStringHelper(this)).toString();
}
/**
*
* @return
*/
+ @Override
InstanceIdentifier<T> build();
/*
package org.opendaylight.yangtools.yang.common;
+import com.google.common.base.MoreObjects;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
import java.util.Arrays;
import java.util.List;
-
-import org.opendaylight.yangtools.yang.common.RpcError;
-import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
import org.opendaylight.yangtools.yang.common.RpcError.ErrorType;
-import com.google.common.base.Objects;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableList;
-
/**
* A general base exception for an operation failure.
*
@Override
public String toString() {
- return Objects.toStringHelper( this ).add( "message", getMessage() )
+ return MoreObjects.toStringHelper( this ).add( "message", getMessage() )
.add( "errorList", errorList ).toString();
}
}
*/
package org.opendaylight.yangtools.yang.common;
-import com.google.common.base.Objects;
+import com.google.common.base.MoreObjects;
import java.io.Serializable;
import java.net.URI;
import java.net.URISyntaxException;
@Override
public String toString() {
- return Objects.toStringHelper(this).omitNullValues().add("ns", getNamespace()).add("rev", getFormattedRevision()).toString();
+ return MoreObjects.toStringHelper(this).omitNullValues().add("ns", getNamespace()).add("rev", getFormattedRevision()).toString();
}
}
import com.google.common.collect.ImmutableList;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
+
+import java.io.Serializable;
import java.util.Collection;
import java.util.Collections;
+
import org.opendaylight.yangtools.concepts.Builder;
import org.opendaylight.yangtools.yang.common.RpcError.ErrorSeverity;
import org.opendaylight.yangtools.yang.common.RpcError.ErrorType;
*/
public final class RpcResultBuilder<T> implements Builder<RpcResult<T>> {
- private static class RpcResultImpl<T> implements RpcResult<T> {
+ private static class RpcResultImpl<T> implements RpcResult<T>, Serializable {
+ private static final long serialVersionUID = 1L;
private final Collection<RpcError> errors;
private final T result;
}
}
- private static class RpcErrorImpl implements RpcError {
+ private static class RpcErrorImpl implements RpcError, Serializable {
+ private static final long serialVersionUID = 1L;
private final String applicationTag;
private final String tag;
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.common;
+
+import java.net.URI;
+
+/**
+ * Constant definitions present in RFC documents related to the YANG language.
+ */
+public final class YangConstants {
+ /**
+ * YANG namespace, as defined in RFC 6020.
+ */
+ public static final URI RFC6020_YANG_NAMESPACE = URI.create("urn:ietf:params:xml:ns:yang:1");
+
+ /**
+ * YIN namespace, as defined in RFC 6020.
+ */
+ public static final URI RFC6020_YIN_NAMESPACE = URI.create("urn:ietf:params:xml:ns:yang:yin:1");
+
+ /**
+ * Base QNameModule for all YANG statements.
+ */
+ public static final QNameModule RFC6020_YANG_MODULE = QNameModule.cachedReference(QNameModule.create(RFC6020_YANG_NAMESPACE, null));
+
+ /**
+ * Base QNameModule for all YIN statements.
+ */
+ public static final QNameModule RFC6020_YIN_MODULE = QNameModule.cachedReference(QNameModule.create(RFC6020_YIN_NAMESPACE, null));
+
+ private YangConstants() {
+ throw new UnsupportedOperationException("Utility class");
+ }
+
+}
import static org.junit.Assert.*;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.List;
"error message", null, null, null );
}
+ @SuppressWarnings("unchecked")
+ @Test
+ public void testSerialization() throws Exception {
+ RpcResult<String> result = RpcResultBuilder.<String>success().withResult( "foo" ).build();
+
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ ObjectOutputStream out = new ObjectOutputStream(bos);
+ out.writeObject(result);
+
+ ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(bos.toByteArray()));
+ RpcResult<String> clone = (RpcResult<String>) in.readObject();
+
+ verifyRpcResult(clone, true, "foo");
+
+ Throwable cause = new Throwable( "mock cause" );
+ result = RpcResultBuilder.<String>failed()
+ .withError( ErrorType.RPC, "in-use", "error message", "my-app-tag", "my-info", cause )
+ .build();
+
+ bos = new ByteArrayOutputStream();
+ out = new ObjectOutputStream(bos);
+ out.writeObject(result);
+
+ in = new ObjectInputStream(new ByteArrayInputStream(bos.toByteArray()));
+ clone = (RpcResult<String>) in.readObject();
+
+ verifyRpcResult(clone, false, null);
+ verifyRpcError( result, 0, ErrorSeverity.ERROR, ErrorType.RPC, "in-use",
+ "error message", "my-app-tag", "my-info", cause );
+ }
+
void verifyRpcError( RpcResult<?> result, int errorIndex, ErrorSeverity expSeverity,
ErrorType expErrorType, String expTag, String expMessage, String expAppTag,
String expInfo, Throwable expCause ) {
package org.opendaylight.yangtools.yang.data.codec.gson;
import com.google.common.base.Preconditions;
-
import org.opendaylight.yangtools.concepts.Codec;
import org.opendaylight.yangtools.yang.data.api.codec.BooleanCodec;
import org.opendaylight.yangtools.yang.data.api.codec.DecimalCodec;
* @param codec underlying codec
* @return A JSONCodec instance
*/
- public static <T> JSONCodec<T> create(final Codec<String, T> codec) {
- if (codec instanceof BooleanCodec || codec instanceof DecimalCodec ||
- codec instanceof Int8Codec || codec instanceof Int16Codec ||
- codec instanceof Int32Codec || codec instanceof Int64Codec ||
- codec instanceof Uint8Codec || codec instanceof Uint16Codec ||
- codec instanceof Uint32Codec || codec instanceof Uint64Codec) {
- return new UnquotedJSONCodec<>(codec);
+ public static JSONCodec<?> create(final Codec<String, ?> codec) {
+ if (codec instanceof BooleanCodec) {
+ return new BooleanJSONCodec((BooleanCodec<String>) codec);
+ } else if (codec instanceof DecimalCodec || codec instanceof Int8Codec
+ || codec instanceof Int16Codec || codec instanceof Int32Codec
+ || codec instanceof Int64Codec || codec instanceof Uint8Codec
+ || codec instanceof Uint16Codec || codec instanceof Uint32Codec
+ || codec instanceof Uint64Codec) {
+ return new NumberJSONCodec(codec);
+ } else {
+ return new QuotedJSONCodec<>(codec);
}
-
- return new QuotedJSONCodec<>(codec);
}
@Override
--- /dev/null
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.data.codec.gson;
+
+import com.google.gson.stream.JsonWriter;
+import java.io.IOException;
+import org.opendaylight.yangtools.concepts.Codec;
+
+/**
+ * A {@link JSONCodec} which does not need double quotes in output representation.
+ *
+ * @param <T> Deserialized value type
+ */
+final class BooleanJSONCodec extends AbstractJSONCodec<Boolean> {
+ BooleanJSONCodec(final Codec<String, Boolean> codec) {
+ super(codec);
+ }
+
+ @Override
+ public boolean needQuotes() {
+ return false;
+ }
+
+ /**
+ * Serialize specified value with specified JsonWriter.
+ *
+ * @param writer JsonWriter
+ * @param value
+ */
+ @Override
+ public void serializeToWriter(JsonWriter writer, Boolean value) throws IOException {
+ writer.value(value);
+ };
+}
\ No newline at end of file
*/
package org.opendaylight.yangtools.yang.data.codec.gson;
+import com.google.gson.stream.JsonWriter;
+import java.io.IOException;
import org.opendaylight.yangtools.concepts.Codec;
interface JSONCodec<T> extends Codec<String, T> {
+ // FIXME: Unused, remove once we are sure we do not need this anymore.
boolean needQuotes();
+
+
+ /**
+ * Serialize specified value with specified JsonWriter.
+ *
+ * @param writer JsonWriter
+ * @param value
+ */
+ void serializeToWriter(JsonWriter writer, T value) throws IOException;
}
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
-
+import com.google.gson.stream.JsonWriter;
+import java.io.IOException;
import org.opendaylight.yangtools.yang.data.impl.codec.TypeDefinitionAwareCodec;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
public boolean needQuotes() {
return false;
}
+
+ @Override
+ public void serializeToWriter(JsonWriter writer, Object value) throws IOException {
+ // NOOP since codec is unkwown.
+ LOG.warn("Call of the serializeToWriter method on JSONCodecFactory.NULL_CODEC object. No operation performed.");
+ }
};
private static TypeDefinition<?> resolveBaseTypeFrom(final TypeDefinition<?> type) {
return NULL_CODEC;
}
- return AbstractJSONCodec.create(codec);
+ return (JSONCodec<Object>) AbstractJSONCodec.create(codec);
}
});
*/
package org.opendaylight.yangtools.yang.data.codec.gson;
+import com.google.gson.stream.JsonWriter;
+import java.io.IOException;
import org.opendaylight.yangtools.yang.data.api.codec.LeafrefCodec;
final class JSONLeafrefCodec implements JSONCodec<Object>, LeafrefCodec<String> {
public boolean needQuotes() {
return true;
}
+
+ /**
+ * Serialize specified value with specified JsonWriter.
+ *
+ * @param writer JsonWriter
+ * @param value
+ */
+ @Override
+ public void serializeToWriter(JsonWriter writer, Object value) throws IOException {
+ writer.value(serialize(value));
+ }
}
\ No newline at end of file
*/
package org.opendaylight.yangtools.yang.data.codec.gson;
-import com.google.common.base.CharMatcher;
import com.google.common.base.Preconditions;
-import com.google.common.base.Strings;
import com.google.gson.stream.JsonWriter;
+import java.io.IOException;
+import java.io.Writer;
+import java.net.URI;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
import org.opendaylight.yangtools.yang.data.impl.codec.SchemaTracker;
import org.opendaylight.yangtools.yang.model.api.AnyXmlSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.SchemaNode;
import org.opendaylight.yangtools.yang.model.api.SchemaPath;
-import java.io.IOException;
-import java.io.Writer;
-import java.net.URI;
-
/**
* This implementation will create JSON output as output stream.
*
* Values of leaf and leaf-list are NOT translated according to codecs.
*
- * FIXME: rewrite this in terms of {@link JsonWriter}.
*/
public class JSONNormalizedNodeStreamWriter implements NormalizedNodeStreamWriter {
/**
*/
private static final boolean DEFAULT_EMIT_EMPTY_CONTAINERS = true;
- /**
- * Matcher used to check if a string needs to be escaped.
- */
- private static final CharMatcher JSON_ILLEGAL_STRING_CHARACTERS = CharMatcher.anyOf("\\\"\n\r");
-
private final SchemaTracker tracker;
private final JSONCodecFactory codecs;
- private final Writer writer;
- private final String indent;
+ private final JsonWriter writer;
private JSONStreamWriterContext context;
- private JSONNormalizedNodeStreamWriter(final JSONCodecFactory codecFactory, final SchemaPath path,
- final Writer writer, final URI initialNs, final int indentSize) {
- this.writer = Preconditions.checkNotNull(writer);
-
- Preconditions.checkArgument(indentSize >= 0, "Indent size must be non-negative");
- if (indentSize != 0) {
- indent = Strings.repeat(" ", indentSize);
- } else {
- indent = null;
- }
+ private JSONNormalizedNodeStreamWriter(final JSONCodecFactory codecFactory, final SchemaPath path, final URI initialNs, JsonWriter JsonWriter) {
+ this.writer = JsonWriter;
this.codecs = Preconditions.checkNotNull(codecFactory);
this.tracker = SchemaTracker.create(codecFactory.getSchemaContext(), path);
this.context = new JSONStreamWriterRootContext(initialNs);
* @return A stream writer instance
*/
public static NormalizedNodeStreamWriter create(final SchemaContext schemaContext, final Writer writer) {
- return new JSONNormalizedNodeStreamWriter(JSONCodecFactory.create(schemaContext), SchemaPath.ROOT, writer, null, 0);
+ return create(schemaContext, SchemaPath.ROOT, null, writer);
}
/**
* @return A stream writer instance
*/
public static NormalizedNodeStreamWriter create(final SchemaContext schemaContext, final SchemaPath path, final Writer writer) {
- return new JSONNormalizedNodeStreamWriter(JSONCodecFactory.create(schemaContext), path, writer, null, 0);
+ return create(schemaContext, path, null, writer);
}
/**
*/
public static NormalizedNodeStreamWriter create(final SchemaContext schemaContext, final SchemaPath path,
final URI initialNs, final Writer writer) {
- return new JSONNormalizedNodeStreamWriter(JSONCodecFactory.create(schemaContext), path, writer, initialNs, 0);
+ return create(JSONCodecFactory.create(schemaContext), path, initialNs, JsonWriterFactory.createJsonWriter(writer));
}
/**
* @return A stream writer instance
*/
public static NormalizedNodeStreamWriter create(final SchemaContext schemaContext, final Writer writer, final int indentSize) {
- return new JSONNormalizedNodeStreamWriter(JSONCodecFactory.create(schemaContext), SchemaPath.ROOT, writer, null, indentSize);
+ return create(JSONCodecFactory.create(schemaContext), SchemaPath.ROOT, null,JsonWriterFactory.createJsonWriter(writer, indentSize));
}
/**
* @return A stream writer instance
*/
public static NormalizedNodeStreamWriter create(final JSONCodecFactory codecFactory, final Writer writer, final int indentSize) {
- return new JSONNormalizedNodeStreamWriter(codecFactory, SchemaPath.ROOT, writer, null, indentSize);
+ return create(codecFactory, SchemaPath.ROOT, null, JsonWriterFactory.createJsonWriter(writer,indentSize));
+ }
+
+ /**
+ * Create a new stream writer, which writes to the specified output stream.
+ *
+ * @param schemaContext Schema context
+ * @param path Schema Path
+ * @param initialNs Initial namespace
+ * @param jsonWriter JsonWriter
+ * @return A stream writer instance
+ */
+ public static NormalizedNodeStreamWriter create(SchemaContext schemaContext, SchemaPath path, URI initialNs,
+ JsonWriter jsonWriter) {
+ return create(JSONCodecFactory.create(schemaContext), path, initialNs, jsonWriter);
+ }
+
+ /**
+ * Create a new stream writer, which writes to the specified output stream. The codec factory
+ * can be reused between multiple writers.
+ *
+ * @param codecFactory JSON codec factory
+ * @param path Schema Path
+ * @param initialNs Initial namespace
+ * @param jsonWriter JsonWriter
+ * @return A stream writer instance
+ */
+ public static NormalizedNodeStreamWriter create(JSONCodecFactory codecFactory, SchemaPath path, URI initialNs, JsonWriter jsonWriter) {
+ return new JSONNormalizedNodeStreamWriter(codecFactory, path, initialNs, jsonWriter);
}
@Override
final LeafSchemaNode schema = tracker.leafNode(name);
final JSONCodec<Object> codec = codecs.codecFor(schema.getType());
- context.emittingChild(codecs.getSchemaContext(), writer, indent);
+ context.emittingChild(codecs.getSchemaContext(), writer);
context.writeChildJsonIdentifier(codecs.getSchemaContext(), writer, name.getNodeType());
- writeValue(codec.serialize(value), codec.needQuotes());
+
+ writeValue(value, codec);
}
@Override
final LeafListSchemaNode schema = tracker.leafSetEntryNode();
final JSONCodec<Object> codec = codecs.codecFor(schema.getType());
- context.emittingChild(codecs.getSchemaContext(), writer, indent);
- writeValue(codec.serialize(value), codec.needQuotes());
+ context.emittingChild(codecs.getSchemaContext(), writer);
+
+ writeValue(value, codec);
}
/*
@SuppressWarnings("unused")
@Override
public void startContainerNode(final NodeIdentifier name, final int childSizeHint) throws IOException {
- final ContainerSchemaNode schema = tracker.startContainerNode(name);
- context = new JSONStreamWriterNamedObjectContext(context, name, DEFAULT_EMIT_EMPTY_CONTAINERS || schema.isPresenceContainer());
+ final SchemaNode schema = tracker.startContainerNode(name);
+
+ // FIXME this code ignores presence for containers
+ // but datastore does as well and it needs be fixed first (2399)
+ context = new JSONStreamWriterNamedObjectContext(context, name, DEFAULT_EMIT_EMPTY_CONTAINERS);
}
@Override
final AnyXmlSchemaNode schema = tracker.anyxmlNode(name);
// FIXME: should have a codec based on this :)
- context.emittingChild(codecs.getSchemaContext(), writer, indent);
+ context.emittingChild(codecs.getSchemaContext(), writer);
context.writeChildJsonIdentifier(codecs.getSchemaContext(), writer, name.getNodeType());
- writeValue(String.valueOf(value), true);
+ writer.value(String.valueOf(value));
}
@Override
public void endNode() throws IOException {
tracker.endNode();
- context = context.endNode(codecs.getSchemaContext(), writer, indent);
+ context = context.endNode(codecs.getSchemaContext(), writer);
+ if(context instanceof JSONStreamWriterRootContext) {
+ context.emitEnd(writer);
+ }
}
- private void writeValue(final String str, final boolean needQuotes) throws IOException {
- if (needQuotes) {
- writer.append('"');
-
- final int needEscape = JSON_ILLEGAL_STRING_CHARACTERS.countIn(str);
- if (needEscape != 0) {
- final char[] escaped = new char[str.length() + needEscape];
- int offset = 0;
-
- for (int i = 0; i < str.length(); i++) {
- final char c = str.charAt(i);
- if (JSON_ILLEGAL_STRING_CHARACTERS.matches(c)) {
- escaped[offset++] = '\\';
- }
- escaped[offset++] = c;
- }
- writer.write(escaped);
- } else {
- writer.append(str);
- }
-
- writer.append('"');
- } else {
- writer.append(str);
- }
+ private void writeValue(Object value, JSONCodec<Object> codec)
+ throws IOException {
+ codec.serializeToWriter(writer,value);
}
@Override
writer.close();
}
+
+
}
package org.opendaylight.yangtools.yang.data.codec.gson;
import com.google.common.base.Preconditions;
+import com.google.gson.stream.JsonWriter;
import java.io.IOException;
-import java.io.Writer;
+import java.io.StringWriter;
import java.net.URI;
import javax.annotation.Nonnull;
import org.opendaylight.yangtools.yang.common.QName;
private final boolean mandatory;
private final int depth;
private boolean emittedMyself = false;
- private boolean haveChild = false;
/**
* Construct a new context.
* @param qname Namespace/name tuple
* @throws IOException when the writer reports it
*/
- final void writeChildJsonIdentifier(final SchemaContext schema, final Writer writer, final QName qname) throws IOException {
- writer.append('"');
+ final void writeChildJsonIdentifier(final SchemaContext schema, final JsonWriter writer, final QName qname) throws IOException {
+ StringWriter strWriter = new StringWriter();
// Prepend module name if namespaces do not match
final URI ns = qname.getNamespace();
if (!ns.equals(getNamespace())) {
final Module module = schema.findModuleByNamespaceAndRevision(ns, null);
Preconditions.checkArgument(module != null, "Could not find module for namespace {}", ns);
- writer.append(module.getName());
- writer.append(':');
+ strWriter.append(module.getName());
+ strWriter.append(':');
}
+ strWriter.append(qname.getLocalName());
- writer.append(qname.getLocalName());
- writer.append("\":");
+ writer.name(strWriter.toString());
}
/**
* @param qname Namespace/name tuple
* @throws IOException when the writer reports it
*/
- protected final void writeMyJsonIdentifier(final SchemaContext schema, final Writer writer, final QName qname) throws IOException {
+ protected final void writeMyJsonIdentifier(final SchemaContext schema, final JsonWriter writer, final QName qname) throws IOException {
parent.writeChildJsonIdentifier(schema, writer, qname);
}
* @param writer Output writer
* @throws IOException
*/
- protected abstract void emitStart(final SchemaContext schema, final Writer writer) throws IOException;
+ protected abstract void emitStart(final SchemaContext schema, final JsonWriter writer) throws IOException;
/**
* Emit the end of an element.
* @param writer Output writer
* @throws IOException
*/
- protected abstract void emitEnd(final Writer writer) throws IOException;
+ protected abstract void emitEnd(final JsonWriter writer) throws IOException;
- private final void emitMyself(final SchemaContext schema, final Writer writer, final String indent) throws IOException {
+ private final void emitMyself(final SchemaContext schema, final JsonWriter writer) throws IOException {
if (!emittedMyself) {
if (parent != null) {
- parent.emittingChild(schema, writer, indent);
+ parent.emittingChild(schema, writer);
}
emitStart(schema, writer);
*
* @param schema Schema context
* @param writer Output writer
- * @param indent Indentation string
* @throws IOException when writer reports it
*/
- final void emittingChild(final SchemaContext schema, final Writer writer, final String indent) throws IOException {
- emitMyself(schema, writer, indent);
- if (haveChild) {
- writer.append(',');
- }
-
- if (indent != null) {
- writer.append('\n');
-
- for (int i = 0; i < depth; i++) {
- writer.append(indent);
- }
- }
- haveChild = true;
+ final void emittingChild(final SchemaContext schema, final JsonWriter writer) throws IOException {
+ emitMyself(schema, writer);
}
/**
*
* @param schema Schema context
* @param writer Output writer
- * @param indent Indentation string
* @return Parent node context
* @throws IOException when writer reports it
* @throws IllegalArgumentException if this node cannot be ended (e.g. root)
*/
- final JSONStreamWriterContext endNode(final SchemaContext schema, final Writer writer, final String indent) throws IOException {
+ final JSONStreamWriterContext endNode(final SchemaContext schema, final JsonWriter writer) throws IOException {
if (!emittedMyself && mandatory) {
- emitMyself(schema, writer, indent);
+ emitMyself(schema, writer);
}
if (emittedMyself) {
package org.opendaylight.yangtools.yang.data.codec.gson;
import com.google.common.base.Preconditions;
+import com.google.gson.stream.JsonWriter;
+
-import java.io.Writer;
/**
* A virtual recursion level in {@link JSONNormalizedNodeStreamWriter}, used for nodes
}
@Override
- protected void emitEnd(final Writer writer) {
+ protected void emitEnd(final JsonWriter writer) {
// No-op
}
}
\ No newline at end of file
package org.opendaylight.yangtools.yang.data.codec.gson;
import com.google.common.base.Preconditions;
+import com.google.gson.stream.JsonWriter;
import java.io.IOException;
-import java.io.Writer;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
}
@Override
- protected void emitStart(final SchemaContext schema, final Writer writer) throws IOException {
+ protected void emitStart(final SchemaContext schema, final JsonWriter writer) throws IOException {
writeMyJsonIdentifier(schema, writer, getQName());
- writer.append('[');
+ writer.beginArray();
}
@Override
- protected void emitEnd(final Writer writer) throws IOException {
- writer.append(']');
+ protected void emitEnd(final JsonWriter writer) throws IOException {
+ writer.endArray();
}
}
*/
package org.opendaylight.yangtools.yang.data.codec.gson;
+import com.google.gson.stream.JsonWriter;
import java.io.IOException;
-import java.io.Writer;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
/**
* A recursion level of {@link JSONNormalizedNodeStreamWriter}, which represents
* a JSON object which has to be prefixed with its identifier -- such as a
}
@Override
- protected void emitStart(final SchemaContext schema, final Writer writer) throws IOException {
+ protected void emitStart(final SchemaContext schema, final JsonWriter writer) throws IOException {
writeMyJsonIdentifier(schema, writer, getQName());
super.emitStart(schema, writer);
}
package org.opendaylight.yangtools.yang.data.codec.gson;
import com.google.common.base.Preconditions;
-
+import com.google.gson.stream.JsonWriter;
import java.io.IOException;
-import java.io.Writer;
-
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
}
@Override
- protected void emitStart(final SchemaContext schema, final Writer writer) throws IOException {
- writer.append('{');
+ protected void emitStart(final SchemaContext schema, final JsonWriter writer) throws IOException {
+ writer.beginObject();
}
@Override
- protected void emitEnd(final Writer writer) throws IOException {
- writer.append('}');
+ protected void emitEnd(final JsonWriter writer) throws IOException {
+ writer.endObject();
}
}
\ No newline at end of file
*/
package org.opendaylight.yangtools.yang.data.codec.gson;
-import java.io.Writer;
+import com.google.gson.stream.JsonWriter;
+import java.io.IOException;
import java.net.URI;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
/**
* The root node of a particular {@link JSONNormalizedNodeStreamWriter} instance.
}
@Override
- protected void emitEnd(final Writer writer) {
- throw new IllegalArgumentException("Top-level node reached");
+ protected void emitStart(final SchemaContext schema, final JsonWriter writer) throws IOException {
+ writer.beginObject();
+ }
+
+ @Override
+ protected void emitEnd(final JsonWriter writer) throws IOException {
+ writer.endObject();
}
}
*/
package org.opendaylight.yangtools.yang.data.codec.gson;
+import com.google.gson.stream.JsonWriter;
import java.io.IOException;
-import java.io.Writer;
import java.net.URI;
-
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
/**
* Abstract class tracking a virtual level of {@link JSONNormalizedNodeStreamWriter}
* recursion. It only tracks the namespace associated with this node.
}
@Override
- protected final void emitStart(final SchemaContext schema, final Writer writer) throws IOException {
+ protected void emitStart(final SchemaContext schema, final JsonWriter writer) throws IOException {
// No-op
}
}
\ No newline at end of file
package org.opendaylight.yangtools.yang.data.codec.gson;
import com.google.common.base.Preconditions;
-
+import com.google.gson.stream.JsonWriter;
+import java.io.IOException;
import java.net.URI;
-
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.data.util.AbstractModuleStringIdentityrefCodec;
import org.opendaylight.yangtools.yang.model.api.Module;
public boolean needQuotes() {
return true;
}
+
+ /**
+ * Serialize QName with specified JsonWriter.
+ *
+ * @param writer JsonWriter
+ * @param value QName
+ */
+ @Override
+ public void serializeToWriter(JsonWriter writer, QName value) throws IOException {
+ writer.value(serialize(value));
+ }
}
package org.opendaylight.yangtools.yang.data.codec.gson;
import com.google.common.base.Preconditions;
-
+import com.google.gson.stream.JsonWriter;
+import java.io.IOException;
import java.net.URI;
-
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.util.AbstractModuleStringInstanceIdentifierCodec;
import org.opendaylight.yangtools.yang.model.api.Module;
public boolean needQuotes() {
return true;
}
+
+ /**
+ * Serialize YangInstanceIdentifier with specified JsonWriter.
+ *
+ * @param writer JsonWriter
+ * @param value YangInstanceIdentifier
+ */
+ @Override
+ public void serializeToWriter(JsonWriter writer, YangInstanceIdentifier value) throws IOException {
+ writer.value(serialize(value));
+ }
}
--- /dev/null
+/**
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.data.codec.gson;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Strings;
+import com.google.gson.stream.JsonWriter;
+import java.io.Writer;
+
+/**
+ * Factory Method class for JsonWriter creation
+ */
+@Beta
+public final class JsonWriterFactory {
+
+ private JsonWriterFactory() {
+ }
+ /**
+ * Create a new JsonWriter, which writes to the specified output writer.
+ *
+ * @param writer Output writer
+ * @return A JsonWriter instance
+ */
+ public static JsonWriter createJsonWriter(Writer writer) {
+ return new JsonWriter(writer);
+ }
+
+ /**
+ * Create a new JsonWriter, which writes to the specified output writer.
+ *
+ * @param writer Output writer
+ * @param indentSize size of the indent
+ * @return A JsonWriter instance
+ */
+ public static JsonWriter createJsonWriter(Writer writer, int indentSize) {
+ JsonWriter jsonWriter = new JsonWriter(writer);
+ final String indent = Strings.repeat(" ", indentSize);
+ jsonWriter.setIndent(indent);
+ return jsonWriter;
+ }
+
+}
*/
package org.opendaylight.yangtools.yang.data.codec.gson;
+import com.google.gson.stream.JsonWriter;
+import java.io.IOException;
import org.opendaylight.yangtools.concepts.Codec;
/**
*
* @param <T> Deserialized value type
*/
-final class UnquotedJSONCodec<T> extends AbstractJSONCodec<T> {
- UnquotedJSONCodec(final Codec<String, T> codec) {
+final class NumberJSONCodec<T extends Number> extends AbstractJSONCodec<T > {
+ NumberJSONCodec(final Codec<String, T> codec) {
super(codec);
}
public boolean needQuotes() {
return false;
}
+
+ /**
+ * Serialize specified value with specified JsonWriter.
+ *
+ * @param writer JsonWriter
+ * @param value
+ */
+ @Override
+ public void serializeToWriter(JsonWriter writer, T value) throws IOException {
+ writer.value(value);
+ }
}
\ No newline at end of file
*/
package org.opendaylight.yangtools.yang.data.codec.gson;
+import com.google.gson.stream.JsonWriter;
+import java.io.IOException;
import org.opendaylight.yangtools.concepts.Codec;
/**
public boolean needQuotes() {
return true;
}
+
+ /**
+ * Serialize specified value with specified JsonWriter.
+ *
+ * @param writer JsonWriter
+ * @param value
+ */
+ @Override
+ public void serializeToWriter(JsonWriter writer, T value) throws IOException {
+ writer.value(serialize(value));
+ }
}
\ No newline at end of file
private String normalizedNodeToJsonStreamTransformation(final Writer writer,
final NormalizedNode<?, ?> inputStructure) throws IOException {
- writer.write("{\n");
+
final NormalizedNodeStreamWriter jsonStream = JSONNormalizedNodeStreamWriter.create(schemaContext, writer, 2);
final NormalizedNodeWriter nodeWriter = NormalizedNodeWriter.forStreamWriter(jsonStream);
nodeWriter.write(inputStructure);
- writer.write("\n}");
+
nodeWriter.close();
return writer.toString();
}
package org.opendaylight.yangtools.yang.data.impl.codec;
import com.google.common.annotations.Beta;
+import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
+import com.google.common.base.Predicate;
+import com.google.common.collect.Iterables;
import java.io.IOException;
import java.util.ArrayDeque;
import java.util.Deque;
import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.GroupingDefinition;
import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.NotificationDefinition;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
import org.opendaylight.yangtools.yang.model.api.SchemaNode;
import org.opendaylight.yangtools.yang.model.api.SchemaPath;
private final DataNodeContainer root;
private SchemaTracker(final SchemaContext context, final SchemaPath path) {
- DataSchemaNode current = Preconditions.checkNotNull(context);
- for (QName qname : path.getPathFromRoot()) {
- final DataSchemaNode child;
+ SchemaNode current = Preconditions.checkNotNull(context);
+ for (final QName qname : path.getPathFromRoot()) {
+ SchemaNode child;
if(current instanceof DataNodeContainer) {
child = ((DataNodeContainer) current).getDataChildByName(qname);
+
+ if (child == null && current instanceof SchemaContext) {
+ child = tryFindGroupings((SchemaContext) current, qname).orNull();
+ }
+
+ if(child == null && current instanceof SchemaContext) {
+ child = tryFindNotification((SchemaContext) current, qname)
+ .orNull();
+ }
} else if (current instanceof ChoiceNode) {
child = ((ChoiceNode) current).getCaseNodeByName(qname);
} else {
- throw new IllegalArgumentException(String.format("Schema node %s does not allow children.",current));
+ throw new IllegalArgumentException(String.format("Schema node %s does not allow children.", current));
}
current = child;
}
Preconditions.checkArgument(current instanceof DataNodeContainer,"Schema path must point to container or list. Supplied path %s pointed to: %s",path,current);
- this.root = (DataNodeContainer) current;
+ root = (DataNodeContainer) current;
+ }
+
+ private Optional<SchemaNode> tryFindGroupings(final SchemaContext ctx, final QName qname) {
+ return Optional.<SchemaNode> fromNullable(Iterables.find(ctx.getGroupings(), new SchemaNodePredicate(qname), null));
+ }
+
+ private Optional<SchemaNode> tryFindNotification(final SchemaContext ctx, final QName qname) {
+ return Optional.<SchemaNode>fromNullable(Iterables.find(ctx.getNotifications(), new SchemaNodePredicate(qname), null));
}
/**
if(parent instanceof DataNodeContainer) {
schema = ((DataNodeContainer)parent).getDataChildByName(qname);
+ if(schema == null && parent instanceof GroupingDefinition) {
+ schema = ((GroupingDefinition) parent);
+ }
+
+ if(schema == null && parent instanceof NotificationDefinition) {
+ schema = ((NotificationDefinition) parent);
+ }
} else if(parent instanceof ChoiceNode) {
- for(ChoiceCaseNode caze : ((ChoiceNode) parent).getCases()) {
- DataSchemaNode potential = caze.getDataChildByName(qname);
+ for(final ChoiceCaseNode caze : ((ChoiceNode) parent).getCases()) {
+ final DataSchemaNode potential = caze.getDataChildByName(qname);
if(potential != null) {
schema = potential;
break;
return (ChoiceNode)schema;
}
- public ContainerSchemaNode startContainerNode(final NodeIdentifier name) {
+ public SchemaNode startContainerNode(final NodeIdentifier name) {
LOG.debug("Enter container {}", name);
final SchemaNode schema = getSchema(name);
- Preconditions.checkArgument(schema instanceof ContainerSchemaNode, "Node %s is not a container", schema.getPath());
+ boolean isAllowed = schema instanceof ContainerSchemaNode;
+ isAllowed |= schema instanceof NotificationDefinition;
+
+ Preconditions.checkArgument(isAllowed, "Node %s is not a container nor a notification", schema.getPath());
schemaStack.push(schema);
- return (ContainerSchemaNode)schema;
+ return schema;
}
public AugmentationSchema startAugmentationNode(final AugmentationIdentifier identifier) {
Preconditions.checkArgument(parent instanceof AugmentationTarget, "Augmentation not allowed under %s", parent);
Preconditions.checkArgument(parent instanceof DataNodeContainer, "Augmentation allowed only in DataNodeContainer",parent);
final AugmentationSchema schema = SchemaUtils.findSchemaForAugment((AugmentationTarget) parent, identifier.getPossibleChildNames());
- HashSet<DataSchemaNode> realChildSchemas = new HashSet<>();
- for(DataSchemaNode child : schema.getChildNodes()) {
+ final HashSet<DataSchemaNode> realChildSchemas = new HashSet<>();
+ for(final DataSchemaNode child : schema.getChildNodes()) {
realChildSchemas.add(((DataNodeContainer) parent).getDataChildByName(child.getQName()));
}
- AugmentationSchema resolvedSchema = new AugmentationSchemaProxy(schema, realChildSchemas);
+ final AugmentationSchema resolvedSchema = new AugmentationSchemaProxy(schema, realChildSchemas);
schemaStack.push(resolvedSchema);
return resolvedSchema;
}
public Object endNode() {
return schemaStack.pop();
}
+
+ private static final class SchemaNodePredicate implements Predicate<SchemaNode> {
+ private final QName qname;
+
+ public SchemaNodePredicate(final QName qname) {
+ this.qname = qname;
+ }
+
+ @Override
+ public boolean apply(final SchemaNode input) {
+ return input.getQName().equals(qname);
+ }
+ }
}
private void writeStartElement( QName qname) throws XMLStreamException {
String ns = qname.getNamespace().toString();
- String parentNs = writer.getNamespaceContext().getNamespaceURI(DEFAULT_NS_PREFIX);
writer.writeStartElement(DEFAULT_NS_PREFIX, qname.getLocalName(), ns);
- if (!ns.equals(parentNs)) {
- writer.writeDefaultNamespace(ns);
+ if(writer.getNamespaceContext() != null) {
+ String parentNs = writer.getNamespaceContext().getNamespaceURI(DEFAULT_NS_PREFIX);
+ if (!ns.equals(parentNs)) {
+ writer.writeDefaultNamespace(ns);
+ }
}
}
package org.opendaylight.yangtools.yang.data.impl.codec.xml;
import static com.google.common.base.Preconditions.checkState;
-
import com.google.common.base.Function;
-import com.google.common.base.Objects;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
+import java.util.Objects;
import java.util.Set;
import javax.activation.UnsupportedDataTypeException;
import javax.annotation.Nonnull;
}
private static void checkQName(final Element xmlElement, final QName qName) {
- checkState(Objects.equal(xmlElement.getNamespaceURI(), qName.getNamespace().toString()), "Not equal: %s to: %s for: %s and: %s", qName.getNamespace(), xmlElement.getNamespaceURI(), qName, xmlElement);
+ checkState(Objects.equals(xmlElement.getNamespaceURI(), qName.getNamespace().toString()), "Not equal: %s to: %s for: %s and: %s", qName.getNamespace(), xmlElement.getNamespaceURI(), qName, xmlElement);
checkState(qName.getLocalName().equals(xmlElement.getLocalName()), "Not equal: %s to: %s for: %s and: %s", qName.getLocalName(), xmlElement.getLocalName(), qName, xmlElement);
}
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
-import com.google.common.base.Objects.ToStringHelper;
+import com.google.common.base.MoreObjects.ToStringHelper;
public abstract class AbstractImmutableDataContainerAttrNode<K extends YangInstanceIdentifier.PathArgument>
extends AbstractImmutableDataContainerNode<K>
*/
package org.opendaylight.yangtools.yang.data.impl.schema.nodes;
-import com.google.common.base.Objects;
-import com.google.common.base.Objects.ToStringHelper;
+import com.google.common.base.MoreObjects;
+import com.google.common.base.MoreObjects.ToStringHelper;
import com.google.common.base.Preconditions;
import org.opendaylight.yangtools.concepts.Immutable;
@Override
public final String toString() {
- return addToStringAttributes(Objects.toStringHelper(this)).toString();
+ return addToStringAttributes(MoreObjects.toStringHelper(this)).toString();
}
protected ToStringHelper addToStringAttributes(final ToStringHelper toStringHelper) {
*/
package org.opendaylight.yangtools.yang.data.impl.schema.nodes;
-import com.google.common.base.Objects.ToStringHelper;
+import com.google.common.base.MoreObjects.ToStringHelper;
import com.google.common.collect.ImmutableMap;
import java.util.Map;
import org.opendaylight.yangtools.yang.common.QName;
*/
package org.opendaylight.yangtools.yang.data.impl.schema.tree;
-import com.google.common.base.Objects;
+import com.google.common.base.MoreObjects;
import com.google.common.base.Preconditions;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodes;
import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.TreeNode;
@Override
public String toString() {
final TreeNode r = root;
- return Objects.toStringHelper(this).add("data", NormalizedNodes.toStringTree(r.getData())).toString();
+ return MoreObjects.toStringHelper(this).add("data", NormalizedNodes.toStringTree(r.getData())).toString();
}
}
\ No newline at end of file
*/
package org.opendaylight.yangtools.yang.data.impl.schema.tree;
-import com.google.common.base.Objects;
+import com.google.common.base.MoreObjects;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import java.util.Collections;
@Override
public String toString() {
- return Objects.toStringHelper(this).add("object", super.toString()).add("state", state).toString();
+ return MoreObjects.toStringHelper(this).add("object", super.toString()).add("state", state).toString();
}
}
<!-- yang-common dependency added here only for purpose of 'artifact version
check' test: version of yang-common artifact has to be different than one defined
in yang-maven-plugin to make test pass -->
- <repositories>
- <repository>
- <id>opendaylight-mirror</id>
- <name>opendaylight-mirror</name>
- <url>http://nexus.opendaylight.org/content/groups/public/</url>
- <snapshots>
- <enabled>false</enabled>
- </snapshots>
- <releases>
- <enabled>true</enabled>
- <updatePolicy>never</updatePolicy>
- </releases>
- </repository>
- </repositories>
<dependencies>
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
<groupId>org.sonatype.plexus</groupId>
<artifactId>plexus-build-api</artifactId>
</dependency>
- <dependency>
- <groupId>org.codehaus.plexus</groupId>
- <artifactId>plexus-slf4j-logging</artifactId>
- </dependency>
</dependencies>
<build>
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang2sources.spi;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+/**
+ * Maven 3.1.x and newer uses SLF4J internally, which means we do not need to pass
+ * a logger instance around.
+ */
+public interface BasicCodeGenerator {
+ /**
+ * Generate sources from provided {@link SchemaContext}
+ *
+ * @param context
+ * parsed from YANG files
+ * @param outputBaseDir
+ * expected output directory for generated sources configured by
+ * user
+ * @param currentModules
+ * YANG modules parsed from yangFilesRootDir
+ * @return collection of files that were generated from schema context
+ * @throws IOException
+ */
+ Collection<File> generateSources(SchemaContext context, File outputBaseDir, Set<Module> currentModules)
+ throws IOException;
+
+ /**
+ * Provided map contains all configuration that was set in pom for code
+ * generator in additionalConfiguration tag
+ *
+ * @param additionalConfiguration
+ */
+ void setAdditionalConfig(Map<String, String> additionalConfiguration);
+
+ /**
+ * Provided folder is marked as resources and its content will be packaged
+ * in resulting jar. Feel free to add necessary resources
+ *
+ * @param resourceBaseDir
+ */
+ void setResourceBaseDir(File resourceBaseDir);
+}
*/
package org.opendaylight.yangtools.yang2sources.spi;
-import java.io.File;
-import java.io.IOException;
-import java.util.Collection;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.maven.plugin.logging.Log;
-import org.apache.maven.project.MavenProject;
-import org.opendaylight.yangtools.yang.model.api.Module;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-
/**
* Classes implementing this interface can be submitted to maven-yang-plugin's
* generate-sources goal.
+ *
+ * @deprecated Use {@link BasicCodeGenerator} with appropriate traits.
*/
-public interface CodeGenerator {
-
- /**
- * Generate sources from provided {@link SchemaContext}
- *
- * @param context
- * parsed from yang files
- * @param outputBaseDir
- * expected output directory for generated sources configured by
- * user
- * @param currentModules
- * yang modules parsed from yangFilesRootDir
- * @return collection of files that were generated from schema context
- * @throws IOException
- */
- Collection<File> generateSources(SchemaContext context, File outputBaseDir, Set<Module> currentModules)
- throws IOException;
-
- /**
- * Utilize maven logging if necessary
- *
- * @param log
- */
- void setLog(Log log);
-
- /**
- * Provided map contains all configuration that was set in pom for code
- * generator in additionalConfiguration tag
- *
- * @param additionalConfiguration
- */
- void setAdditionalConfig(Map<String, String> additionalConfiguration);
-
- /**
- * Provided folder is marked as resources and its content will be packaged
- * in resulting jar. Feel free to add necessary resources
- *
- * @param resourceBaseDir
- */
- void setResourceBaseDir(File resourceBaseDir);
+@Deprecated
+public interface CodeGenerator extends BasicCodeGenerator, MavenLogAware, MavenProjectAware {
- /**
- * Provided maven project object. Any additional information about current
- * maven project can be accessed from it.
- *
- * @param project
- */
- void setMavenProject(MavenProject project);
}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang2sources.spi;
+
+import org.apache.maven.plugin.logging.Log;
+
+/**
+ * Bridge compatibility class for plugins using the maven logger functionality.
+ *
+ * @deprecated Use slf4j logging directly.
+ */
+@Deprecated
+public interface MavenLogAware {
+ /**
+ * Utilize maven logging if necessary
+ *
+ * @param log maven log instance
+ */
+ void setLog(Log log);
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang2sources.spi;
+
+import org.apache.maven.project.MavenProject;
+
+/**
+ * Bridge for plugins which need access to the underlying maven project.
+ */
+public interface MavenProjectAware {
+ /**
+ * Provided maven project object. Any additional information about current
+ * maven project can be accessed from it.
+ *
+ * @param project
+ */
+ void setMavenProject(MavenProject project);
+}
import org.opendaylight.yangtools.yang.model.api.Module;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-public class CodeGeneratorTestImpl implements CodeGenerator {
+public class CodeGeneratorTestImpl implements BasicCodeGenerator, MavenLogAware, MavenProjectAware {
private Log log;
<groupId>org.sonatype.plexus</groupId>
<artifactId>plexus-build-api</artifactId>
</dependency>
- <dependency>
- <groupId>org.codehaus.plexus</groupId>
- <artifactId>plexus-slf4j-logging</artifactId>
- </dependency>
<dependency>
<groupId>commons-io</groupId>
private static Class<?> resolveClass(String codeGeneratorClass, Class<?> baseType) throws ClassNotFoundException {
Class<?> clazz = Class.forName(codeGeneratorClass);
- if (!isImplemented(baseType, clazz)) {
+ if (!baseType.isAssignableFrom(clazz)) {
throw new IllegalArgumentException("Code generator " + clazz + " has to implement " + baseType);
}
return clazz;
}
- private static boolean isImplemented(Class<?> expectedIface, Class<?> byClazz) {
- for (Class<?> iface : byClazz.getInterfaces()) {
- if (iface.equals(expectedIface)) {
- return true;
- }
- }
- return false;
- }
-
static String message(String message, String logPrefix, Object... args) {
String innerMessage = String.format(message, args);
return String.format("%s %s", logPrefix, innerMessage);
import org.opendaylight.yangtools.yang2sources.plugin.ConfigArg.CodeGeneratorArg;
import org.opendaylight.yangtools.yang2sources.plugin.Util.ContextHolder;
import org.opendaylight.yangtools.yang2sources.plugin.Util.YangsInZipsResult;
+import org.opendaylight.yangtools.yang2sources.spi.BasicCodeGenerator;
import org.opendaylight.yangtools.yang2sources.spi.BuildContextAware;
-import org.opendaylight.yangtools.yang2sources.spi.CodeGenerator;
+import org.opendaylight.yangtools.yang2sources.spi.MavenLogAware;
+import org.opendaylight.yangtools.yang2sources.spi.MavenProjectAware;
import org.sonatype.plexus.build.incremental.BuildContext;
import org.sonatype.plexus.build.incremental.DefaultBuildContext;
codeGeneratorCfg.check();
- CodeGenerator g = Util.getInstance(codeGeneratorCfg.getCodeGeneratorClass(), CodeGenerator.class);
+ BasicCodeGenerator g = Util.getInstance(codeGeneratorCfg.getCodeGeneratorClass(), BasicCodeGenerator.class);
log.info(Util.message("Code generator instantiated from %s", LOG_PREFIX,
codeGeneratorCfg.getCodeGeneratorClass()));
log.debug(Util.message("Additional configuration picked up for : %s: %s", LOG_PREFIX,
codeGeneratorCfg.getCodeGeneratorClass(), codeGeneratorCfg.getAdditionalConfiguration()));
+ if (g instanceof MavenLogAware) {
+ ((MavenLogAware)g).setLog(log);
+ }
if (g instanceof BuildContextAware) {
((BuildContextAware)g).setBuildContext(buildContext);
}
- g.setLog(log);
- g.setMavenProject(project);
+ if (g instanceof MavenProjectAware) {
+ ((MavenProjectAware)g).setMavenProject(project);
+ }
g.setAdditionalConfig(codeGeneratorCfg.getAdditionalConfiguration());
File resourceBaseDir = codeGeneratorCfg.getResourceBaseDir(project);
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
import org.opendaylight.yangtools.yang2sources.plugin.ConfigArg.CodeGeneratorArg;
import org.opendaylight.yangtools.yang2sources.plugin.YangToSourcesProcessor.YangProvider;
-import org.opendaylight.yangtools.yang2sources.spi.CodeGenerator;
+import org.opendaylight.yangtools.yang2sources.spi.BasicCodeGenerator;
+import org.opendaylight.yangtools.yang2sources.spi.MavenLogAware;
+import org.opendaylight.yangtools.yang2sources.spi.MavenProjectAware;
public class GenerateSourcesTest {
+ "generated-sources" + File.separator + "spi"));
}
- public static class GeneratorMock implements CodeGenerator {
+ public static class GeneratorMock implements BasicCodeGenerator, MavenLogAware, MavenProjectAware {
private static int called = 0;
private static File outputDir;
*/
package org.opendaylight.yangtools.yang.model.api;
+
/**
* The ContainerSchemaNode is used to define an interior data node in the schema
* tree. There are two styles of containers, those that exist only for
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Preconditions;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.YangConstants;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
+import org.opendaylight.yangtools.yang.model.api.stmt.AnyxmlStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.ArgumentStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.AugmentStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.BaseStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.BelongsToStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.BitStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.CaseStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.ChoiceStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.ConfigStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.ContactStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.ContainerStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.DefaultStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.DescriptionStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.DeviateStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.DeviationStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.EnumStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.ErrorAppTagStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.ErrorMessageStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.ExtensionStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.FeatureStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.FractionDigitsStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.GroupingStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.IdentityStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.IfFeatureStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.ImportStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.IncludeStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.InputStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.KeyStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.LeafListStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.LeafStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.LengthStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.ListStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.MandatoryStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.MaxElementsStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.MinElementsStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.ModuleStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.MustStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.NamespaceStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.NotificationStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.OrderedByStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.OrganizationStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.OutputStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.PathStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.PatternStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.PositionStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.PrefixStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.PresenceStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.RangeStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.ReferenceStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.RefineStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.RequireInstanceStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.RevisionDateStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.RevisionStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.RpcStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.StatusStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.SubmoduleStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.TypeStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.TypedefStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.UniqueStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.UnitsStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.UsesStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.ValueStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.WhenStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.YangVersionStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.YinElementStatement;
+
+@Beta
+public enum Rfc6020Mapping implements StatementDefinition {
+ Anyxml(AnyxmlStatement.class, "anyxml", "name"),
+ Argument(ArgumentStatement.class, "argument", "name"),
+ Augment(AugmentStatement.class, "augment", "target-node"),
+ Base(BaseStatement.class, "base", "name"),
+ BelongsTo(BelongsToStatement.class, "belongs-to", "module"),
+ Bit(BitStatement.class, "bit", "name"),
+ Case(CaseStatement.class, "case", "name"),
+ Choice(ChoiceStatement.class, "choice", "name"),
+ Config(ConfigStatement.class, "config", "value"),
+ Contact(ContactStatement.class, "contact", "text", true),
+ Container(ContainerStatement.class, "container", "name"),
+ Default(DefaultStatement.class, "default", "value"),
+ Description(DescriptionStatement.class, "description", "text", true),
+ Deviate(DeviateStatement.class, "deviate", "value"),
+ Deviation(DeviationStatement.class, "deviation", "target-node"),
+ Enum(EnumStatement.class, "enum", "name"),
+ ErrorAppTag(ErrorAppTagStatement.class, "error-app-tag", "value"),
+ ErrorMessage(ErrorMessageStatement.class, "error-message", "value", true),
+ Extension(ExtensionStatement.class, "extension", "name"),
+ Feature(FeatureStatement.class, "feature", "name"),
+ FractionDigits(FractionDigitsStatement.class, "fraction-digits", "value"),
+ Grouping(GroupingStatement.class, "grouping", "name"),
+ Identity(IdentityStatement.class, "identity", "name"),
+ IfFeature(IfFeatureStatement.class, "if-feature", "name"),
+ Import(ImportStatement.class, "import", "module"),
+ Include(IncludeStatement.class, "include", "module"),
+ Input(InputStatement.class, "input"),
+ Key(KeyStatement.class, "key", "value"),
+ Leaf(LeafStatement.class, "leaf", "name"),
+ LeafList(LeafListStatement.class, "leaf-list", "name"),
+ Length(LengthStatement.class, "length", "value"),
+ List(ListStatement.class, "list", "name"),
+ Mandatory(MandatoryStatement.class, "mandatory", "value"),
+ MaxElements(MaxElementsStatement.class, "max-elements", "value"),
+ MinElements(MinElementsStatement.class, "min-elements", "value"),
+ Module(ModuleStatement.class, "module", "name"),
+ Must(MustStatement.class, "must", "condition"),
+ Namespace(NamespaceStatement.class, "namespace", "uri"),
+ Notification(NotificationStatement.class, "notification", "name"),
+ OrderedBy(OrderedByStatement.class, "ordered-by", "value"),
+ Organization(OrganizationStatement.class, "organization", "text", true),
+ Output(OutputStatement.class, "output"),
+ Path(PathStatement.class, "path", "value"),
+ Pattern(PatternStatement.class, "pattern", "value"),
+ Position(PositionStatement.class, "position", "value"),
+ Prefix(PrefixStatement.class, "prefix", "value"),
+ Presence(PresenceStatement.class, "presence", "value"),
+ Range(RangeStatement.class, "range", "value"),
+ Reference(ReferenceStatement.class, "reference", "text", true),
+ Refine(RefineStatement.class, "refine", "target-node"),
+ RequireInstance(RequireInstanceStatement.class, "require-instance", "value"),
+ Revision(RevisionStatement.class, "revision", "date"),
+ RevisionDate(RevisionDateStatement.class, "revision-date", "date"),
+ Rpc(RpcStatement.class, "rpc", "name"),
+ Status(StatusStatement.class, "status", "value"),
+ Submodule(SubmoduleStatement.class, "submodule", "name"),
+ Type(TypeStatement.class, "type", "name"),
+ Typedef(TypedefStatement.class, "typedef", "name"),
+ Unique(UniqueStatement.class, "unique", "tag"),
+ Units(UnitsStatement.class, "units", "name"),
+ Uses(UsesStatement.class, "uses", "name"),
+ Value(ValueStatement.class, "value", "value"),
+ When(WhenStatement.class, "when", "condition"),
+ YangVersion(YangVersionStatement.class, "yang-version", "value"),
+ YinElement(YinElementStatement.class, "yin-element", "value");
+
+ private final @Nonnull Class<? extends DeclaredStatement<?>> type;
+ private final @Nonnull QName name;
+ private final @Nullable QName argument;
+ private final boolean yinElement;
+
+
+ private Rfc6020Mapping(Class<? extends DeclaredStatement<?>> clz, final String nameStr) {
+ type = Preconditions.checkNotNull(clz);
+ name = yinQName(nameStr);
+ argument = null;
+ yinElement = false;
+ }
+
+ private Rfc6020Mapping(Class<? extends DeclaredStatement<?>> clz, final String nameStr, final String argumentStr) {
+ type = Preconditions.checkNotNull(clz);
+ name = yinQName(nameStr);
+ argument = yinQName(argumentStr);
+ this.yinElement = false;
+ }
+
+ private Rfc6020Mapping(Class<? extends DeclaredStatement<?>> clz, final String nameStr, final String argumentStr,
+ final boolean yinElement) {
+ type = Preconditions.checkNotNull(clz);
+ name = yinQName(nameStr);
+ argument = yinQName(argumentStr);
+ this.yinElement = yinElement;
+ }
+
+ private static QName yinQName(String nameStr) {
+ return QName.cachedReference(QName.create(YangConstants.RFC6020_YIN_MODULE, nameStr));
+ }
+
+ @Override
+ public QName getStatementName() {
+ return name;
+ }
+
+ @Override
+ public QName getArgumentName() {
+ return argument;
+ }
+
+ @Override
+ public Class<? extends DeclaredStatement<?>> getDeclaredRepresentationClass() {
+ return type;
+ }
+
+ @Override
+ public Class<? extends DeclaredStatement<?>> getEffectiveRepresentationClass() {
+ // FIXME: Add support once these interfaces are defined.
+ throw new UnsupportedOperationException("Not defined yet.");
+ }
+
+ public boolean isArgumentYinElement() {
+ return yinElement;
+ }
+}
+
*/
package org.opendaylight.yangtools.yang.model.api;
-import com.google.common.base.Objects;
-import com.google.common.base.Objects.ToStringHelper;
+import com.google.common.base.MoreObjects;
+import com.google.common.base.MoreObjects.ToStringHelper;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
@Override
public final String toString() {
- return addToStringAttributes(Objects.toStringHelper(this)).toString();
+ return addToStringAttributes(MoreObjects.toStringHelper(this)).toString();
}
protected ToStringHelper addToStringAttributes(final ToStringHelper toStringHelper) {
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.meta;
+
+import java.util.Collection;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+/**
+ * Represents declared statement
+ *
+ * @param <A> Argument type ({@link Void} if statement does not have argument.)
+ */
+public interface DeclaredStatement<A> extends ModelStatement<A> {
+
+ /**
+ *
+ * Returns statement argument as was present in original source.
+ *
+ * @return statement argument as was present in original source or null, if statement does not take argument.
+ */
+ @Nullable String rawArgument();
+
+ /**
+ *
+ * Returns collection of explicitly declared child statements, while preserving its original
+ * ordering from original source.
+ *
+ * @return Collection of statements, which were explicitly declared in
+ * source of model.
+ */
+ @Nonnull Collection<? extends DeclaredStatement<?>> declaredSubstatements();
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.meta;
+
+import java.util.Collection;
+import java.util.Map;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+/**
+ * Effective model statement which should be used to derive application behaviour.
+ *
+ * @param <A>
+ * Argument type ({@link Void} if statement does not have argument.)
+ * @param <S>
+ * Class representing declared version of this statement.
+ */
+public interface EffectiveStatement<A, S extends DeclaredStatement<A>> extends ModelStatement<A> {
+
+ /**
+ * Returns statement, which was explicit declaration of this effective
+ * statement.
+ *
+ *
+ * @return statement, which was explicit declaration of this effective
+ * statement or null if statement was inferred from context.
+ */
+ @Nullable
+ S getDeclared();
+
+ /**
+ *
+ * Returns value associated with supplied identifier
+ *
+ * @param <K>
+ * Identifier type
+ * @param <V>
+ * Value type
+ * @param <N>
+ * Namespace identifier type
+ * @param namespace
+ * Namespace type
+ * @param identifier
+ * Identifier of element.
+ * @return Value if present, null otherwise.
+ *
+ *
+ */
+ @Nullable
+ <K, V, N extends IdentifierNamespace<? super K, ? extends V>> V get(@Nonnull Class<N> namespace,@Nonnull K identifier);
+
+ /**
+ *
+ * Returns all local values from supplied namespace.
+ *
+ * @param <K>
+ * Identifier type
+ * @param <V>
+ * Value type
+ * @param <N>
+ * Namespace identifier type
+ * @param namespace
+ * Namespace type
+ * @return Value if present, null otherwise.
+ */
+ @Nullable
+ <K, V, N extends IdentifierNamespace<K, V>> Map<K, V> getAll(@Nonnull Class<N> namespace);
+
+ /**
+ *
+ * Returns iteration of all effective substatements.
+ *
+ * @return iteration of all effective substatements.
+ */
+ Collection<? extends EffectiveStatement<?, ?>> effectiveSubstatements();
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.meta;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+/**
+ *
+ * Model specific namespace which allows access to specific
+ *
+ * {@link IdentifierNamespace} serves as common superclass for YANG model
+ * namespaces, which are type-captured subclasses. This type capture
+ * of namespace allows for handy type-safe reading methods
+ * such as {@link EffectiveStatement#get(Class, Object)} and still
+ * allows introduction of new namespaces without need to change
+ * model APIs.
+ *
+ * @param <K> Identifier type
+ * @param <V> Value type
+ */
+public interface IdentifierNamespace<K,V> {
+
+ /**
+ *
+ * Returns value associated with supplied identifier
+ *
+ * @param identifier Identifier of value
+ * @return value or null, if identifier is not present in namespace.
+ */
+ @Nullable V get(@Nonnull K identifier);
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.meta;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+/**
+ *
+ * Model statement
+ *
+ * There are two base types of model statements:
+ * <ul>
+ * <li>{@link DeclaredStatement} - Statement representation as was defined in original
+ * source. This representation could be used during computation of effective model
+ * or during transforming YANG model from one serialization format to other.
+ * </li>
+ * <li>
+ * {@link EffectiveStatement} - Representation of effective statement - this
+ * statement may be different from declared, in such way, that it contains additional
+ * substatements, provides access to model namespaces. Some effective statements may be not
+ * directly declared in YANG source, but could be inferred by semantic processing of
+ * other statements (eg. uses, augment).
+ * </li>
+ * </ul>
+ *
+ * @param <A> Argument type ({@link Void} if statement does not have argument.)
+ */
+public interface ModelStatement<A> {
+
+ /**
+ * Statement Definition of this statement.
+ *
+ * @return definition of this statement.
+ */
+ @Nonnull StatementDefinition statementDefinition();
+
+ /**
+ *
+ * Returns statement argument
+ *
+ * @return statement argument or null if statement does not have argument.
+ */
+ @Nullable A argument();
+
+ /**
+ * Returns statement source, which denotes if statement was
+ * explicitly declared in original model or inferred during
+ * semantic processing of model.
+ *
+ * @return statement source.
+ */
+ @Nonnull StatementSource getStatementSource();
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.meta;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import org.opendaylight.yangtools.concepts.Immutable;
+import org.opendaylight.yangtools.yang.common.QName;
+
+/**
+ *
+ * Definition / model of YANG {@link DeclaredStatement} and {@link EffectiveStatement}.
+ *
+ * Statement concept is defined in RFC6020 section 6.3:
+ * <blockquote> A YANG
+ * module contains a sequence of statements. Each statement starts with a
+ * keyword, followed by zero or one argument
+ * </blockquote>
+ *
+ * Source: <a href="https://tools.ietf.org/html/rfc6020#section-6.3"> </a>
+ *
+ *
+ */
+public interface StatementDefinition extends Immutable {
+
+ /**
+ *
+ * Returns name of the statement
+ *
+ * @return Name of the statement
+ */
+ @Nonnull
+ QName getStatementName();
+
+ /**
+ *
+ * Returns name of statement argument or null, if statement does not have
+ * argument.
+ *
+ * @return argument name or null, if statement does not take argument.
+ */
+ @Nullable
+ QName getArgumentName();
+
+ /**
+ *
+ * Returns class which represents declared version of statement associated
+ * with this definition.
+ *
+ * This class should be interface, which provides convenience access to
+ * declared substatements.
+ *
+ * @return class which represents declared version of statement associated
+ * with this definition.
+ */
+ @Nonnull
+ Class<? extends DeclaredStatement<?>> getDeclaredRepresentationClass();
+
+ /**
+ *
+ * Returns class which represents supplied statement.
+ *
+ * This class should be interface, which defines convenience access to
+ * statement properties, namespace items and substatements.
+ *
+ * @return class which represents declared version of statement associated
+ * with this definition
+ */
+ @Nonnull
+ Class<? extends DeclaredStatement<?>> getEffectiveRepresentationClass();
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.meta;
+/**
+ *
+ * Origin of statement
+ *
+ * Represents origin of statement - if it was explicitly present
+ * in model representation or if it was inferred from context.
+ *
+ */
+public enum StatementSource {
+
+ /**
+ *
+ * Statement was explicitly declared by author
+ * of the supplied model.
+ *
+ */
+ DECLARATION,
+ /**
+ *
+ * Statement was derived from context of YANG model / statement
+ * and represents effective model.
+ *
+ * Effective context nodes are derived from applicable {@link #DECLARATION}
+ * statements by interpreting their semantic meaning in context
+ * of current statement.
+ *
+ */
+ CONTEXT
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+/**
+ * Meta model of YANG model as was defined in RFC6020 and extracted by analysis
+ * of YANG text.
+ *
+ * <p>
+ * Existence of meta-model allows for better evolution of YANG language as it evolves
+ * and allows for better support of different serializations of YANG model.
+ *
+ * <h2>Statements</h2>
+ * YANG source is defined as sequence of statement in
+ * <a href="https://tools.ietf.org/html/rfc6020#section-6.3">RFC6020, Section 6.3</a>.
+ * this model is also correct for YIN, which is XML serialisation of YANG source.
+ * <p>
+ * Statements are represented as instances / subclasses of {@link org.opendaylight.yangtools.yang.model.api.meta.ModelStatement}
+ * concept and its two subconcepts which are:
+ * <ul>
+ * <li>
+ * {@link org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement} - this contains navigable
+ * set of statements model as they was defined / present in original processed
+ * sources.
+ * </li>
+ * <li>{@link org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement} - navigable set of statements
+ * which represents effective model of parsed YANG sources, which is derived by rules
+ * present in YANG specification and/or was introduced in form of extensions.
+ * </li>
+ * </ul>
+ * <p>
+ * Clear separation of declared / effective model is needed, since statement definition also
+ * contains information how effective model is computed and there is no one to one mapping
+ * between declared and effective model thanks to statements such as {@code uses},
+ * {@code augment},{@code deviate},{@code refine}.
+ *
+ * <h2>Identifiers and Namespaces</h2>
+ * Effective model of YANG has several identifier types and namespaces, which behaves differently
+ * and are mostly used during processing data and/or during computing effective (semantic) model.
+ * <p>
+ * Common abstraction for various types of namespaces is {@link org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace}
+ * from which concrete effective model namespaces are derived.
+ *
+ */
+package org.opendaylight.yangtools.yang.model.api.meta;
\ No newline at end of file
*/
/**
- * Definition of structures and DOM Like API of processed YANG schema
+ * Definition of structures and DOM like API of effected YANG schema
*
- * <h3>YANG Statement mapping</h3>
+ * <p>
+ * This package is structured into following logical units:
+ * <dl>
+ * <dt>YANG Meta model</dt>
+ * <dd>Meta model of YANG, which defines basic concepts and building blocks of YANG models
+ * such as {@link org.opendaylight.yangtools.yang.model.api.meta.ModelStatement}.</dd>
+ * <dt>YANG Statement model</dt>
+ * <dd>Concrete java model of YANG statements, which defines basic relationship between statements
+ * and represents these statements.</dd>
+ *
+ * <dt>YANG Effective model</dt>
+ * <dd>Effective model of processed YANG models, which represents semantic interpretation
+ * of YANG models and provides convenience views for interpreting models.
+ * </dd>
+ * </dl>
+ *
+ *
+ * <h2>YANG Effective model</h2>
+ * <h3>Effective model statement mapping</h3>
*
* <dl>
* <dt>anyxml
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import java.util.Collection;
+import javax.annotation.Nullable;
+
+public interface AnyxmlStatement extends DataDefinitionStatement {
+
+ @Nullable Collection<? extends MustStatement> getMusts();
+
+ @Nullable ConfigStatement getConfig();
+
+ @Nullable MandatoryStatement getMandatory();
+
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+
+
+@Rfc6020AbnfRule("argument-stmt")
+public interface ArgumentStatement extends DeclaredStatement<QName> {
+
+ @Nonnull String getName();
+
+ @Nullable YinElementStatement getYinElement();
+
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface AugmentStatement extends DeclaredStatement<SchemaNodeIdentifier> , DataDefinitionContainer {
+
+ @Nonnull SchemaNodeIdentifier getTargetNode();
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface BaseStatement extends DeclaredStatement<QName> {
+
+ @Nonnull QName getName();
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface BelongsToStatement extends DeclaredStatement<String> {
+
+ @Nonnull String getModule();
+
+ @Nonnull PrefixStatement getPrefix();
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface BitStatement extends DeclaredStatement<String>, DocumentationGroup.WithStatus {
+
+ @Nonnull String getName();
+
+ @Nullable PositionStatement getPosition();
+
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import java.util.Collection;
+import javax.annotation.Nonnull;
+
+
+@Rfc6020AbnfRule("body-stmts")
+public interface BodyGroup extends DataDefinitionContainer.WithReusableDefinitions {
+
+ @Nonnull Collection<? extends ExtensionStatement> getExtensions();
+
+ @Nonnull Collection<? extends FeatureStatement> getFeatures();
+
+ @Nonnull Collection<? extends IdentityStatement> getIdentities();
+
+ @Nonnull Collection<? extends AugmentStatement> getAugments();
+
+ @Nonnull Collection<? extends RpcStatement> getRpcs();
+
+ @Nonnull Collection<? extends NotificationStatement> getNotifications();
+
+ @Nonnull Collection<? extends DeviationStatement> getDeviations();
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+
+public interface CaseStatement extends DeclaredStatement<QName>, DataDefinitionContainer, DocumentationGroup.WithStatus, ConditionalDataDefinition {
+
+ @Nonnull QName getName();
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import java.util.Collection;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+
+
+public interface ChoiceStatement extends DataDefinitionStatement {
+
+ @Nullable DefaultStatement getDefault();
+
+ @Nullable ConfigStatement getConfig();
+
+ @Nullable MandatoryStatement getMandatory();
+
+ @Nonnull Collection<? extends CaseStatement> getCases();
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+public interface ConditionalDataDefinition extends ConditionalFeature {
+
+ WhenStatement getWhenStatement();
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import java.util.Collection;
+import javax.annotation.Nonnull;
+
+
+@Rfc6020AbnfRule("*(if-feature-stmt)")
+public interface ConditionalFeature {
+
+ @Nonnull Collection<? extends IfFeatureStatement> getIfFeatures();
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface ConfigStatement extends DeclaredStatement<Boolean> {
+
+ @Nonnull Boolean getValue();
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface ContactStatement extends DeclaredStatement<String> {
+
+ @Nonnull String getText();
+
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import java.util.Collection;
+import javax.annotation.Nullable;
+
+
+public interface ContainerStatement extends DataDefinitionStatement, DataDefinitionContainer.WithReusableDefinitions {
+
+ @Nullable Collection<? extends MustStatement> getMusts();
+
+ @Nullable PresenceStatement getPresence();
+
+ @Nullable ConfigStatement getConfig();
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import java.util.Collection;
+
+
+public interface DataDefinitionContainer {
+
+ Collection<? extends DataDefinitionStatement> getDataDefinitions();
+
+
+ public interface WithReusableDefinitions extends DataDefinitionContainer {
+
+ Collection<? extends TypedefStatement> getTypedefs();
+
+ Collection<? extends GroupingStatement> getGroupings();
+
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+/**
+ *
+ * Statement that defines new data nodes.
+ *
+ * One of container, leaf, leaf-list, list, choice, case,
+ * augment, uses, and anyxml.
+ *
+ *
+ * Defined in: https://tools.ietf.org/html/rfc6020#section-3
+ *
+ */
+@Rfc6020AbnfRule("data-def-stmt")
+public interface DataDefinitionStatement extends DeclaredStatement<QName>, DocumentationGroup.WithStatus, ConditionalDataDefinition {
+
+ @Nonnull QName getName();
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface DefaultStatement extends DeclaredStatement<String> {
+
+ @Nonnull String getValue();
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface DescriptionStatement extends DeclaredStatement<String> {
+
+ @Nonnull String getText();
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface DeviateStatement extends DeclaredStatement<String> {
+
+ @Nonnull String getValue();
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface DeviationStatement extends DeclaredStatement<SchemaNodeIdentifier> {
+
+
+ @Nonnull SchemaNodeIdentifier getTargetNode();
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nullable;
+
+public interface DocumentationGroup {
+
+ @Nullable DescriptionStatement getDescription();
+
+ @Nullable ReferenceStatement getReference();
+
+
+
+ public interface WithStatus extends DocumentationGroup {
+
+ @Nullable StatusStatement getStatus();
+
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nullable;
+
+public interface DocumentedConstraintGroup extends DocumentationGroup {
+
+ @Nullable ErrorAppTagStatement getErrorAppTagStatement();
+
+ @Nullable ErrorMessageStatement getErrorMessageStatement();
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface EnumStatement extends DeclaredStatement<String>, DocumentationGroup.WithStatus {
+
+ @Nonnull String getName();
+
+ @Nullable ValueStatement getValue();
+
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface ErrorAppTagStatement extends DeclaredStatement<String> {
+
+ @Nonnull String getValue();
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface ErrorMessageStatement extends DeclaredStatement<String> {
+
+ @Nonnull String getValue();
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nullable;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface ExtensionStatement extends DeclaredStatement<QName>, DocumentationGroup.WithStatus {
+
+ @Nullable ArgumentStatement getArgument();
+
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface FeatureStatement extends DeclaredStatement<QName>, DocumentationGroup.WithStatus, ConditionalFeature {
+
+ @Nonnull QName getName();
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+
+public interface FractionDigitsStatement extends DeclaredStatement<String> {
+
+ String getValue();
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+
+public interface GroupingStatement extends DeclaredStatement<QName>, DocumentationGroup.WithStatus,DataDefinitionContainer.WithReusableDefinitions {
+
+ @Nonnull QName getName();
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface IdentityStatement extends DeclaredStatement<QName>, DocumentationGroup.WithStatus {
+
+ @Nonnull String getName();
+
+ @Nullable BaseStatement getBase();
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface IfFeatureStatement extends DeclaredStatement<QName> {
+
+ @Nonnull QName getName();
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface ImportStatement extends DeclaredStatement<String> {
+
+ @Nonnull String getModule();
+
+ @Nonnull PrefixStatement getPrefix();
+
+ @Nullable RevisionDateStatement getRevisionDate();
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface IncludeStatement extends DeclaredStatement<String> {
+
+ @Nonnull String getModule();
+
+ @Nonnull PrefixStatement getPrefix();
+
+ @Nullable RevisionDateStatement getRevisionDate();
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface InputStatement extends DeclaredStatement<Void>, DataDefinitionContainer.WithReusableDefinitions {
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import java.util.Collection;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface KeyStatement extends DeclaredStatement<Collection<SchemaNodeIdentifier>> {
+
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import java.util.Collection;
+import javax.annotation.Nullable;
+
+
+
+public interface LeafListStatement extends DataDefinitionStatement, MultipleElementsGroup, TypeGroup {
+
+ @Nullable Collection<? extends MustStatement> getMusts();
+
+ @Nullable ConfigStatement getConfig();
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import java.util.Collection;
+import javax.annotation.Nullable;
+
+
+
+public interface LeafStatement extends DataDefinitionStatement, TypeGroup {
+
+ @Nullable Collection<? extends MustStatement> getMusts();
+
+ @Nullable DefaultStatement getDefault();
+
+ @Nullable ConfigStatement getConfig();
+
+ @Nullable MandatoryStatement getMandatory();
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface LengthStatement extends DeclaredStatement<String>, DocumentedConstraintGroup {
+
+ @Nonnull String getValue();
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import java.util.Collection;
+import javax.annotation.Nonnull;
+
+
+@Rfc6020AbnfRule("linkage-stms")
+public interface LinkageGroup {
+
+ @Nonnull Collection<? extends ImportStatement> getImports();
+
+ @Nonnull Collection<? extends IncludeStatement> getIncludes();
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import java.util.Collection;
+import javax.annotation.Nullable;
+
+public interface ListStatement extends DataDefinitionStatement, MultipleElementsGroup,
+ DataDefinitionContainer.WithReusableDefinitions {
+
+ Collection<? extends MustStatement> getMusts();
+
+ @Nullable KeyStatement getKey();
+
+ Collection<? extends UniqueStatement> getUnique();
+
+ @Nullable ConfigStatement getConfig();
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface MandatoryStatement extends DeclaredStatement<String> {
+
+ @Nonnull String getValue();
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface MaxElementsStatement extends DeclaredStatement<String> {
+
+ @Nonnull String getValue();
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nullable;
+
+
+@Rfc6020AbnfRule("meta-stmts")
+public interface MetaGroup extends DocumentationGroup {
+
+ @Nullable OrganizationStatement getOrganization();
+
+ @Nullable ContactStatement getContact();
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface MinElementsStatement extends DeclaredStatement<String> {
+
+ @Nonnull String getValue();
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+@Rfc6020AbnfRule("module-header-stmts")
+public interface ModuleHeaderGroup {
+
+ @Nullable YangVersionStatement getYangVersion();
+ @Nonnull NamespaceStatement getNamespace();
+ @Nonnull PrefixStatement getPrefix();
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface ModuleStatement extends DeclaredStatement<String>, ModuleHeaderGroup, LinkageGroup, MetaGroup,
+ RevisionGroup, BodyGroup
+
+ {
+
+ @Nonnull String getName();
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nullable;
+
+public interface MultipleElementsGroup {
+
+ @Nullable MinElementsStatement getMinElements();
+
+ @Nullable MaxElementsStatement getMaxElements();
+
+ @Nullable OrderedByStatement getOrderedBy();
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.model.api.RevisionAwareXPath;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface MustStatement extends DeclaredStatement<RevisionAwareXPath>, DocumentedConstraintGroup {
+
+ @Nonnull RevisionAwareXPath getCondition();
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import java.net.URI;
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface NamespaceStatement extends DeclaredStatement<URI> {
+
+ @Nonnull URI getUri();
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface NotificationStatement extends DeclaredStatement<QName> {
+
+ @Nonnull QName getName();
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface OrderedByStatement extends DeclaredStatement<String> {
+
+ @Nonnull String getValue();
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface OrganizationStatement extends DeclaredStatement<String> {
+
+ @Nonnull String getText();
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface OutputStatement extends DeclaredStatement<Void>, DataDefinitionContainer.WithReusableDefinitions {
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.model.api.RevisionAwareXPath;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface PathStatement extends DeclaredStatement<RevisionAwareXPath> {
+
+ // FIXME: Introduce proper type representing parsed leafref
+ @Nonnull String getValue();
+
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface PatternStatement extends DeclaredStatement<String>, DocumentedConstraintGroup {
+
+ @Nonnull String getValue();
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface PositionStatement extends DeclaredStatement<String> {
+
+ @Nonnull String getValue();
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface PrefixStatement extends DeclaredStatement<String> {
+
+ @Nonnull String getValue();
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface PresenceStatement extends DeclaredStatement<String> {
+
+ @Nonnull String getValue();
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface RangeStatement extends DeclaredStatement<String>, DocumentedConstraintGroup {
+
+ @Nonnull String getRange();
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface ReferenceStatement extends DeclaredStatement<String> {
+
+ @Nonnull String getText();
+
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import java.util.Collection;
+import javax.annotation.Nullable;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+
+public interface RefineStatement extends DeclaredStatement<SchemaNodeIdentifier>, DocumentationGroup {
+
+ String getTargetNode();
+
+ public interface RefineContainerStatement extends RefineStatement {
+
+ Collection<? extends MustStatement> getMusts();
+
+ @Nullable ConfigStatement getConfig();
+
+ @Nullable PresenceStatement getPresence();
+
+ }
+
+ public interface RefineLeafStatement extends RefineStatement {
+
+ Collection<? extends MustStatement> getMusts();
+
+ @Nullable DefaultStatement getDefault();
+
+ @Nullable ConfigStatement getConfig();
+
+ @Nullable PresenceStatement getPresence();
+
+ }
+
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+
+public interface RequireInstanceStatement extends DeclaredStatement<Boolean> {
+
+ @Nonnull String getValue();
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface RevisionDateStatement extends DeclaredStatement<String> {
+
+ String getDate();
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import java.util.Collection;
+
+
+@Rfc6020AbnfRule("revision-stmts")
+public interface RevisionGroup {
+
+ Collection<? extends RevisionStatement> getRevisions();
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface RevisionStatement extends DeclaredStatement<String>, DocumentationGroup {
+
+ String getDate();
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+*
+* References ABNF rule defined in RFC6020 - YANG Specification.
+*
+* <p>
+* An interface / class annotated with this annotation
+* is Java representation of data represented by ABNF rule
+* provided as {@link #value()}. Java representation
+* does not need to be direct,
+* but must retain all information in some, publicly
+* accessible form for consumers.
+* </p>
+* <p>
+* Note that this annotation is used currently only for documentation
+* and does not affect any runtime behaviour.
+* </p>
+*
+*/
+@Documented
+@Retention(RetentionPolicy.SOURCE)
+@interface Rfc6020AbnfRule {
+
+ String[] value();
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface RpcStatement extends DeclaredStatement<QName> {
+
+ String getName();
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import com.google.common.base.Objects;
+import com.google.common.base.Objects.ToStringHelper;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
+import org.opendaylight.yangtools.concepts.Immutable;
+import org.opendaylight.yangtools.yang.common.QName;
+
+/**
+ * Represents unique path to the every schema node inside the schema node identifier
+ * namespace.
+ *
+ */
+public abstract class SchemaNodeIdentifier implements Immutable {
+ /**
+ * An absolute schema node identifier.
+ */
+ public static final class Absolute extends SchemaNodeIdentifier {
+ private Absolute(final SchemaNodeIdentifier parent, final QName qname) {
+ super(parent, qname);
+ }
+
+ @Override
+ public boolean isAbsolute() {
+ return true;
+ }
+
+ @Override
+ protected SchemaNodeIdentifier createInstance(final SchemaNodeIdentifier parent, final QName qname) {
+ return new Absolute(parent, qname);
+ }
+ }
+
+ /**
+ * A relative schema node identifier.
+ */
+ public static class Relative extends SchemaNodeIdentifier {
+ private Relative(final SchemaNodeIdentifier parent, final QName qname) {
+ super(parent, qname);
+ }
+
+ @Override
+ public boolean isAbsolute() {
+ return false;
+ }
+
+ @Override
+ protected SchemaNodeIdentifier createInstance(final SchemaNodeIdentifier parent, final QName qname) {
+ return new Relative(parent, qname);
+ }
+ }
+
+ @SuppressWarnings("rawtypes")
+ private static final AtomicReferenceFieldUpdater<SchemaNodeIdentifier, ImmutableList> LEGACYPATH_UPDATER =
+ AtomicReferenceFieldUpdater.newUpdater(SchemaNodeIdentifier.class, ImmutableList.class, "legacyPath");
+
+ /**
+ * Shared instance of the conceptual root schema node.
+ */
+ public static final SchemaNodeIdentifier ROOT = new Absolute(null, null);
+
+ /**
+ * Shared instance of the "same" relative schema node.
+ */
+ public static final SchemaNodeIdentifier SAME = new Relative(null, null);
+
+ /**
+ * Parent path.
+ */
+ private final SchemaNodeIdentifier parent;
+
+ /**
+ * This component.
+ */
+ private final QName qname;
+
+ /**
+ * Cached hash code. We can use this since we are immutable.
+ */
+ private final int hash;
+
+ /**
+ * Cached legacy path, filled-in when {@link #getPath()} or {@link #getPathTowardsRoot()}
+ * is invoked.
+ */
+ private volatile ImmutableList<QName> legacyPath;
+
+ private ImmutableList<QName> getLegacyPath() {
+ ImmutableList<QName> ret = legacyPath;
+ if (ret == null) {
+ ret = ImmutableList.copyOf(getPathTowardsRoot()).reverse();
+ LEGACYPATH_UPDATER.lazySet(this, ret);
+ }
+
+ return ret;
+ }
+
+ /**
+ * Returns the complete path to schema node.
+ *
+ * @return list of <code>QName</code> instances which represents complete
+ * path to schema node
+ *
+ * @deprecated Use {@link #getPathFromRoot()} instead.
+ */
+ @Deprecated
+ public List<QName> getPath() {
+ return getLegacyPath();
+ }
+
+ protected SchemaNodeIdentifier(final SchemaNodeIdentifier parent, final QName qname) {
+ this.parent = parent;
+ this.qname = qname;
+
+ int h = parent == null ? 0 : parent.hashCode();
+ if (qname != null) {
+ h = h * 31 + qname.hashCode();
+ }
+
+ hash = h;
+ }
+
+ /**
+ * Constructs new instance of this class with the concrete path.
+ *
+ * @param path
+ * list of QName instances which specifies exact path to the
+ * module node
+ * @param absolute
+ * boolean value which specifies if the path is absolute or
+ * relative
+ *
+ * @return A SchemaPath instance.
+ */
+ public static SchemaNodeIdentifier create(final Iterable<QName> path, final boolean absolute) {
+ final SchemaNodeIdentifier parent = absolute ? ROOT : SAME;
+ return parent.createChild(path);
+ }
+
+ /**
+ * Constructs new instance of this class with the concrete path.
+ *
+ * @param absolute
+ * boolean value which specifies if the path is absolute or
+ * relative
+ * @param path
+ * one or more QName instances which specifies exact path to the
+ * module node
+ *
+ * @return A SchemaPath instance.
+ */
+ public static SchemaNodeIdentifier create(final boolean absolute, final QName... path) {
+ return create(Arrays.asList(path), absolute);
+ }
+
+ /**
+ * Create a new instance.
+ *
+ * @param parent Parent schema node identifier
+ * @param qname next path element
+ * @return A new SchemaPath instance
+ */
+ protected abstract SchemaNodeIdentifier createInstance(SchemaNodeIdentifier parent, QName qname);
+
+ /**
+ * Create a child path based on concatenation of this path and a relative path.
+ *
+ * @param relative Relative path
+ * @return A new child path
+ */
+ public SchemaNodeIdentifier createChild(final Iterable<QName> relative) {
+ if (Iterables.isEmpty(relative)) {
+ return this;
+ }
+
+ SchemaNodeIdentifier parent = this;
+ for (QName qname : relative) {
+ parent = parent.createInstance(parent, qname);
+ }
+
+ return parent;
+ }
+
+ /**
+ * Create a child path based on concatenation of this path and a relative path.
+ *
+ * @param relative Relative SchemaPath
+ * @return A new child path
+ */
+ public SchemaNodeIdentifier createChild(final SchemaNodeIdentifier relative) {
+ Preconditions.checkArgument(!relative.isAbsolute(), "Child creation requires relative path");
+
+ SchemaNodeIdentifier parent = this;
+ for (QName qname : relative.getPathFromRoot()) {
+ parent = parent.createInstance(parent, qname);
+ }
+
+ return parent;
+ }
+
+ /**
+ * Create a child path based on concatenation of this path and additional
+ * path elements.
+ *
+ * @param elements Relative SchemaPath elements
+ * @return A new child path
+ */
+ public SchemaNodeIdentifier createChild(final QName... elements) {
+ return createChild(Arrays.asList(elements));
+ }
+
+ /**
+ * Returns the list of nodes which need to be traversed to get from the
+ * starting point (root for absolute SchemaPaths) to the node represented
+ * by this object.
+ *
+ * @return list of <code>qname</code> instances which represents
+ * path from the root to the schema node.
+ */
+ public Iterable<QName> getPathFromRoot() {
+ return getLegacyPath();
+ }
+
+ /**
+ * Returns the list of nodes which need to be traversed to get from this
+ * node to the starting point (root for absolute SchemaPaths).
+ *
+ * @return list of <code>qname</code> instances which represents
+ * path from the schema node towards the root.
+ */
+ public Iterable<QName> getPathTowardsRoot() {
+ return new Iterable<QName>() {
+ @Override
+ public Iterator<QName> iterator() {
+ return new Iterator<QName>() {
+ private SchemaNodeIdentifier current = SchemaNodeIdentifier.this;
+
+ @Override
+ public boolean hasNext() {
+ return current.parent != null;
+ }
+
+ @Override
+ public QName next() {
+ if (current.parent != null) {
+ final QName ret = current.qname;
+ current = current.parent;
+ return ret;
+ } else {
+ throw new NoSuchElementException("No more elements available");
+ }
+ }
+
+ @Override
+ public void remove() {
+ throw new UnsupportedOperationException("Component removal not supported");
+ }
+ };
+ }
+ };
+ }
+
+ /**
+ * Returns the immediate parent SchemaPath.
+ *
+ * @return Parent path, null if this SchemaPath is already toplevel.
+ */
+ public SchemaNodeIdentifier getParent() {
+ return parent;
+ }
+
+ /**
+ * Get the last component of this path.
+ *
+ * @return The last component of this path.
+ */
+ public final QName getLastComponent() {
+ return qname;
+ }
+
+ /**
+ * Describes whether schema node identifier is|isn't absolute.
+ *
+ * @return boolean value which is <code>true</code> if schema path is
+ * absolute.
+ */
+ public abstract boolean isAbsolute();
+
+ @Override
+ public final int hashCode() {
+ return hash;
+ }
+
+ @Override
+ public boolean equals(final Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ final SchemaNodeIdentifier other = (SchemaNodeIdentifier) obj;
+
+ if (qname != null) {
+ if (!qname.equals(other.qname)) {
+ return false;
+ }
+ } else {
+ if (other.qname != null) {
+ return false;
+ }
+ }
+
+ if (parent == null) {
+ return other.parent == null;
+ }
+ return parent.equals(other.parent);
+ }
+
+ @Override
+ public final String toString() {
+ return addToStringAttributes(Objects.toStringHelper(this)).toString();
+ }
+
+ protected ToStringHelper addToStringAttributes(final ToStringHelper toStringHelper) {
+ return toStringHelper.add("path", getPathFromRoot());
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface StatusStatement extends DeclaredStatement<String> {
+
+ @Nonnull String getValue();
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface SubmoduleStatement extends
+ DeclaredStatement<String>,
+ LinkageGroup,
+ MetaGroup,
+ RevisionGroup,
+ BodyGroup {
+
+ @Nonnull String getName();
+
+ @Nullable YangVersionStatement getYangVersion();
+
+ @Nonnull BelongsToStatement getBelongsTo();
+
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+public interface TypeGroup {
+
+ @Nonnull TypeStatement getType();
+
+ @Nullable UnitsStatement getUnits();
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import java.util.Collection;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+@Rfc6020AbnfRule("type-stmt")
+public interface TypeStatement extends DeclaredStatement<QName> {
+
+ @Nonnull String getName();
+
+ @Rfc6020AbnfRule("numerical-restrictions")
+ interface NumericalRestrictions extends TypeStatement {
+
+ @Nonnull RangeStatement getRange();
+
+ }
+
+ @Rfc6020AbnfRule("decimal64-specification")
+ interface Decimal64Specification extends TypeStatement {
+
+ @Nonnull FractionDigitsStatement getFractionDigits();
+
+ @Nullable RangeStatement getRange();
+
+ }
+
+ @Rfc6020AbnfRule("string-restrictions")
+ interface StringRestrictions extends TypeStatement {
+
+ @Nullable LengthStatement getLength();
+
+ @Nonnull Collection<? extends PatternStatement> getPatterns();
+ }
+
+ @Rfc6020AbnfRule("enum-specification")
+ interface EnumSpecification extends TypeStatement {
+
+ @Nonnull Collection<? extends EnumStatement> getEnums();
+
+ }
+
+ @Rfc6020AbnfRule("leafref-specification")
+ interface LeafrefSpecification extends TypeStatement {
+
+ @Nullable PathStatement getPath();
+
+ }
+
+ interface InstanceIdentifierSpecification extends TypeStatement {
+
+ @Nullable RequireInstanceStatement getRequireInstance();
+ }
+
+
+ interface IdentityRefSpecification extends TypeStatement {
+
+ }
+ interface BitsSpecification extends TypeStatement {
+
+ @Nonnull Collection<? extends BitStatement> getBits();
+
+ }
+
+ interface UnionSpecification extends TypeStatement {
+
+ @Nonnull Collection<? extends TypeStatement> getTypes();
+
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface TypedefStatement extends DeclaredStatement<QName>,DocumentationGroup.WithStatus, TypeGroup {
+
+
+ @Nonnull String getName();
+
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import java.util.Collection;
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface UniqueStatement extends DeclaredStatement<Collection<SchemaNodeIdentifier.Relative>> {
+
+ @Nonnull Collection<SchemaNodeIdentifier.Relative> getTag();
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+
+public interface UnitsStatement extends DeclaredStatement<String> {
+
+ @Nonnull String getName();
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nullable;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface UnknownStatement<S> extends DeclaredStatement<S> {
+
+ @Nullable String getArgument();
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import java.util.Collection;
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.common.QName;
+
+
+
+public interface UsesStatement extends DataDefinitionStatement {
+
+ @Override
+ @Nonnull QName getName();
+
+ @Nonnull Collection<? extends RefineStatement> getRefines();
+
+ @Nonnull Collection<? extends AugmentStatement> getAugments();
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+
+public interface ValueStatement extends DeclaredStatement<String> {
+
+ @Nonnull String getValue();
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.model.api.RevisionAwareXPath;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface WhenStatement extends DeclaredStatement<RevisionAwareXPath>, DocumentationGroup {
+
+ @Nonnull RevisionAwareXPath getCondition();
+
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface YangVersionStatement extends DeclaredStatement<String> {
+
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+
+public interface YinElementStatement extends DeclaredStatement<String> {
+
+ @Nonnull String getValue();
+}
+
package org.opendaylight.yangtools.yang.model.repo.api;
import com.google.common.annotations.Beta;
-import com.google.common.base.Objects;
-import com.google.common.base.Objects.ToStringHelper;
+import com.google.common.base.MoreObjects;
+import com.google.common.base.MoreObjects.ToStringHelper;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.Multimap;
-
import java.util.Collection;
import java.util.Collections;
-
import javax.annotation.Nonnull;
-
import org.opendaylight.yangtools.yang.model.api.ModuleImport;
/**
@Override
public final String toString() {
- return addToStringAttributes(Objects.toStringHelper(this).add("unsatisfiedImports", unsatisfiedImports)).toString();
+ return addToStringAttributes(MoreObjects.toStringHelper(this).add("unsatisfiedImports", unsatisfiedImports)).toString();
}
protected ToStringHelper addToStringAttributes(final ToStringHelper toStringHelper) {
import static com.google.common.base.Preconditions.checkArgument;
import com.google.common.annotations.Beta;
-import com.google.common.base.Objects;
-import com.google.common.base.Objects.ToStringHelper;
+import com.google.common.base.MoreObjects;
+import com.google.common.base.MoreObjects.ToStringHelper;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.google.common.io.ByteSource;
@Override
public final String toString() {
- return addToStringAttributes(Objects.toStringHelper(this).add("identifier", identifier)).toString();
+ return addToStringAttributes(MoreObjects.toStringHelper(this).add("identifier", identifier)).toString();
}
/**
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- vi: set et smarttab sw=4 tabstop=4: -->
+<!--
+ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ and is available at http://www.eclipse.org/legal/epl-v10.html
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+ <parent>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>yangtools-parent</artifactId>
+ <version>0.7.0-SNAPSHOT</version>
+ <relativePath>/../../common/parent/pom.xml</relativePath>
+ </parent>
+
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>yang-model-export</artifactId>
+ <name>${project.artifactId}</name>
+ <description>${project.artifactId}</description>
+
+ <dependencies>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>yang-model-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>yang-model-util</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>yang-parser-impl</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>ch.qos.logback</groupId>
+ <artifactId>logback-classic</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>xmlunit</groupId>
+ <artifactId>xmlunit</artifactId>
+ <version>1.5</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <configuration>
+ <instructions>
+ <Bundle-Name>${project.groupId}.${project.artifactId}</Bundle-Name>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.export;
+
+import java.util.List;
+import org.opendaylight.yangtools.yang.model.api.type.BinaryTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.LengthConstraint;
+import org.opendaylight.yangtools.yang.model.util.ExtendedType;
+
+class DerivedBinary extends NormalizatedDerivedType<BinaryTypeDefinition> implements BinaryTypeDefinition {
+
+ public DerivedBinary(final ExtendedType definition) {
+ super(BinaryTypeDefinition.class, definition);
+ }
+
+ @Override
+ BinaryTypeDefinition createDerived(final ExtendedType base) {
+ return new DerivedBinary(base);
+ }
+
+ @Override
+ public List<LengthConstraint> getLengthConstraints() {
+ return delegate().getLengthConstraints();
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.export;
+
+import java.util.List;
+import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition;
+import org.opendaylight.yangtools.yang.model.util.ExtendedType;
+
+class DerivedBits extends NormalizatedDerivedType<BitsTypeDefinition> implements BitsTypeDefinition {
+
+ public DerivedBits(final ExtendedType definition) {
+ super(BitsTypeDefinition.class, definition);
+ }
+
+ @Override
+ BitsTypeDefinition createDerived(final ExtendedType base) {
+ return new DerivedBits(base);
+ }
+
+ @Override
+ public List<Bit> getBits() {
+ return getBaseType().getBits();
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.export;
+
+import org.opendaylight.yangtools.yang.model.api.type.BooleanTypeDefinition;
+import org.opendaylight.yangtools.yang.model.util.ExtendedType;
+
+class DerivedBoolean extends NormalizatedDerivedType<BooleanTypeDefinition> implements BooleanTypeDefinition {
+
+ public DerivedBoolean(final ExtendedType definition) {
+ super(BooleanTypeDefinition.class, definition);
+ }
+
+ @Override
+ BooleanTypeDefinition createDerived(final ExtendedType base) {
+ return new DerivedBoolean(base);
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.export;
+
+import java.util.List;
+import org.opendaylight.yangtools.yang.model.api.type.DecimalTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.RangeConstraint;
+import org.opendaylight.yangtools.yang.model.util.ExtendedType;
+
+class DerivedDecimal extends NormalizatedDerivedType<DecimalTypeDefinition> implements DecimalTypeDefinition {
+
+ public DerivedDecimal(final ExtendedType definition) {
+ super(DecimalTypeDefinition.class, definition);
+ }
+
+ @Override
+ DecimalTypeDefinition createDerived(final ExtendedType base) {
+ return new DerivedDecimal(base);
+ }
+
+ @Override
+ public List<RangeConstraint> getRangeConstraints() {
+ return delegate().getRangeConstraints();
+ }
+
+ @Override
+ public Integer getFractionDigits() {
+ return delegate().getFractionDigits();
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.export;
+
+import java.util.List;
+import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition;
+import org.opendaylight.yangtools.yang.model.util.ExtendedType;
+
+class DerivedEnum extends NormalizatedDerivedType<EnumTypeDefinition> implements EnumTypeDefinition {
+
+ public DerivedEnum(final ExtendedType definition) {
+ super(EnumTypeDefinition.class, definition);
+ }
+
+ @Override
+ EnumTypeDefinition createDerived(final ExtendedType base) {
+ return new DerivedEnum(base);
+ }
+
+ @Override
+ public List<EnumPair> getValues() {
+ return getBaseType().getValues();
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.export;
+
+import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode;
+import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition;
+import org.opendaylight.yangtools.yang.model.util.ExtendedType;
+
+class DerivedIdentityref extends NormalizatedDerivedType<IdentityrefTypeDefinition> implements
+ IdentityrefTypeDefinition {
+
+ public DerivedIdentityref(final ExtendedType definition) {
+ super(IdentityrefTypeDefinition.class, definition);
+ }
+
+ @Override
+ IdentityrefTypeDefinition createDerived(final ExtendedType base) {
+ return new DerivedIdentityref(base);
+ }
+
+ @Override
+ public IdentitySchemaNode getIdentity() {
+ // FIXME: Is this really correct?
+ return getBaseType().getIdentity();
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.export;
+
+import org.opendaylight.yangtools.yang.model.api.RevisionAwareXPath;
+import org.opendaylight.yangtools.yang.model.api.type.InstanceIdentifierTypeDefinition;
+import org.opendaylight.yangtools.yang.model.util.ExtendedType;
+
+class DerivedInstanceIdentifier extends NormalizatedDerivedType<InstanceIdentifierTypeDefinition> implements
+ InstanceIdentifierTypeDefinition {
+
+ public DerivedInstanceIdentifier(final ExtendedType definition) {
+ super(InstanceIdentifierTypeDefinition.class, definition);
+ }
+
+ @Override
+ InstanceIdentifierTypeDefinition createDerived(final ExtendedType base) {
+ return new DerivedInstanceIdentifier(base);
+ }
+
+ @Override
+ public RevisionAwareXPath getPathStatement() {
+ throw new UnsupportedOperationException("Path statement is not part of instance-identifier type");
+ }
+
+ @Override
+ public boolean requireInstance() {
+ return getBaseType().requireInstance();
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.export;
+
+import java.util.List;
+import org.opendaylight.yangtools.yang.model.api.type.IntegerTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.RangeConstraint;
+import org.opendaylight.yangtools.yang.model.util.ExtendedType;
+
+class DerivedInteger extends NormalizatedDerivedType<IntegerTypeDefinition> implements IntegerTypeDefinition {
+
+ public DerivedInteger(final ExtendedType definition) {
+ super(IntegerTypeDefinition.class, definition);
+ }
+
+ @Override
+ IntegerTypeDefinition createDerived(final ExtendedType base) {
+ return new DerivedInteger(base);
+ }
+
+ @Override
+ public List<RangeConstraint> getRangeConstraints() {
+ return delegate().getRangeConstraints();
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.export;
+
+import org.opendaylight.yangtools.yang.model.api.RevisionAwareXPath;
+import org.opendaylight.yangtools.yang.model.api.type.LeafrefTypeDefinition;
+import org.opendaylight.yangtools.yang.model.util.ExtendedType;
+
+class DerivedLeafref extends NormalizatedDerivedType<LeafrefTypeDefinition> implements LeafrefTypeDefinition {
+
+ public DerivedLeafref(final ExtendedType definition) {
+ super(LeafrefTypeDefinition.class, definition);
+ }
+
+ @Override
+ LeafrefTypeDefinition createDerived(final ExtendedType base) {
+ return new DerivedLeafref(base);
+ }
+
+ @Override
+ public RevisionAwareXPath getPathStatement() {
+ return getBaseType().getPathStatement();
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.export;
+
+import java.util.List;
+import org.opendaylight.yangtools.yang.model.api.type.LengthConstraint;
+import org.opendaylight.yangtools.yang.model.api.type.PatternConstraint;
+import org.opendaylight.yangtools.yang.model.api.type.StringTypeDefinition;
+import org.opendaylight.yangtools.yang.model.util.ExtendedType;
+
+class DerivedString extends NormalizatedDerivedType<StringTypeDefinition> implements StringTypeDefinition {
+
+ public DerivedString(final ExtendedType definition) {
+ super(StringTypeDefinition.class, definition);
+ }
+
+ @Override
+ StringTypeDefinition createDerived(final ExtendedType base) {
+ return new DerivedString(base);
+ }
+
+ @Override
+ public List<LengthConstraint> getLengthConstraints() {
+ return delegate().getLengthConstraints();
+ }
+
+ @Override
+ public List<PatternConstraint> getPatternConstraints() {
+ return delegate().getPatternConstraints();
+ }
+
+
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.export;
+
+import java.util.List;
+import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition;
+import org.opendaylight.yangtools.yang.model.util.ExtendedType;
+
+class DerivedUnion extends NormalizatedDerivedType<UnionTypeDefinition> implements UnionTypeDefinition {
+
+ public DerivedUnion(final ExtendedType definition) {
+ super(UnionTypeDefinition.class, definition);
+ }
+
+ @Override
+ UnionTypeDefinition createDerived(final ExtendedType base) {
+ return new DerivedUnion(base);
+ }
+
+ @Override
+ public List<TypeDefinition<?>> getTypes() {
+ return getBaseType().getTypes();
+ }
+
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.export;
+
+import java.util.List;
+import org.opendaylight.yangtools.yang.model.api.type.RangeConstraint;
+import org.opendaylight.yangtools.yang.model.api.type.UnsignedIntegerTypeDefinition;
+import org.opendaylight.yangtools.yang.model.util.ExtendedType;
+
+class DerivedUnsignedInteger extends NormalizatedDerivedType<UnsignedIntegerTypeDefinition> implements
+ UnsignedIntegerTypeDefinition {
+
+ public DerivedUnsignedInteger(final ExtendedType definition) {
+ super(UnsignedIntegerTypeDefinition.class, definition);
+ }
+
+ @Override
+ UnsignedIntegerTypeDefinition createDerived(final ExtendedType base) {
+ return new DerivedUnsignedInteger(base);
+ }
+
+ @Override
+ public List<RangeConstraint> getRangeConstraints() {
+ return delegate().getRangeConstraints();
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.export;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.ExtensionDefinition;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
+
+final class ExtensionStatement implements StatementDefinition {
+
+ private QName argumentName;
+ private QName statementName;
+ private boolean yinElement;
+
+ private ExtensionStatement(final ExtensionDefinition def) {
+ statementName = def.getQName();
+ argumentName = def.getArgument() != null ? QName.create(statementName, def.getArgument()) : null;
+ yinElement = def.isYinElement();
+ }
+
+ static StatementDefinition from(final ExtensionDefinition def) {
+ return new ExtensionStatement(def);
+ }
+
+ static Map<QName,StatementDefinition> mapFrom(final Collection<ExtensionDefinition> definitions) {
+ final HashMap<QName,StatementDefinition> ret = new HashMap<>(definitions.size());
+ for(final ExtensionDefinition def : definitions) {
+ final StatementDefinition value = from(def);
+ ret.put(value.getStatementName(), value);
+ }
+ return ret;
+ }
+
+ @Override
+ public QName getArgumentName() {
+ return argumentName;
+ }
+
+ @Override
+ public QName getStatementName() {
+ return statementName;
+ }
+
+ public boolean isArgumentYinElement() {
+ return yinElement;
+ }
+
+ @Override
+ public Class<? extends DeclaredStatement<?>> getDeclaredRepresentationClass() {
+ throw new UnsupportedOperationException("Not defined");
+ }
+
+ @Override
+ public Class<? extends DeclaredStatement<?>> getEffectiveRepresentationClass() {
+ throw new UnsupportedOperationException("Not defined");
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.export;
+
+import com.google.common.base.Preconditions;
+import java.util.List;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+import org.opendaylight.yangtools.yang.model.api.Status;
+import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.type.BinaryTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.BooleanTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.DecimalTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.InstanceIdentifierTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.IntegerTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.LeafrefTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.StringTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.UnsignedIntegerTypeDefinition;
+import org.opendaylight.yangtools.yang.model.util.ExtendedType;
+
+/**
+ *
+ * Implementations of derived type.
+ *
+ * This is set of utility classes which implements derived YANG type,
+ * preserving original implemented interface instead of {@link ExtendedType}
+ * which does not preserve final type of data.
+ *
+ * FIXME: Lithium: Should be move to yang-model-util package or deprecated
+ * if linking parser is reworked to adhere to base type contract
+ */
+abstract class NormalizatedDerivedType<T extends TypeDefinition<T>> implements TypeDefinition<T> {
+
+ private final ExtendedType definition;
+ private final Class<T> publicType;
+
+ NormalizatedDerivedType(final Class<T> publicType, final ExtendedType delegate) {
+ this.definition = Preconditions.checkNotNull(delegate);
+ this.publicType = Preconditions.checkNotNull(publicType);
+ }
+
+ static TypeDefinition<?> from(final ExtendedType type) {
+ TypeDefinition<? extends TypeDefinition<?>> baseType = type;
+ while (baseType.getBaseType() != null) {
+ baseType = baseType.getBaseType();
+ }
+ if (baseType instanceof BinaryTypeDefinition) {
+ return new DerivedBinary(type);
+ }
+ if (baseType instanceof BooleanTypeDefinition) {
+ return new DerivedBoolean(type);
+ }
+ if (baseType instanceof DecimalTypeDefinition) {
+ return new DerivedDecimal(type);
+ }
+ if (baseType instanceof IdentityrefTypeDefinition) {
+ return new DerivedIdentityref(type);
+ }
+ if (baseType instanceof InstanceIdentifierTypeDefinition) {
+ return new DerivedInstanceIdentifier(type);
+ }
+ if (baseType instanceof IntegerTypeDefinition) {
+ return new DerivedInteger(type);
+ }
+ if (baseType instanceof LeafrefTypeDefinition) {
+ return new DerivedLeafref(type);
+ }
+ if (baseType instanceof UnsignedIntegerTypeDefinition) {
+ return new DerivedUnsignedInteger(type);
+ }
+ if (baseType instanceof StringTypeDefinition) {
+ return new DerivedString(type);
+ }
+ if(baseType instanceof UnionTypeDefinition) {
+ return new DerivedUnion(type);
+ }
+ if(baseType instanceof EnumTypeDefinition) {
+ return new DerivedEnum(type);
+ }
+ if(baseType instanceof BitsTypeDefinition) {
+ return new DerivedBits(type);
+ }
+ throw new IllegalArgumentException("Not supported base type of " + baseType.getClass());
+ }
+
+ @Override
+ public final QName getQName() {
+ return definition.getQName();
+ }
+
+ @Override
+ public final SchemaPath getPath() {
+ return definition.getPath();
+ }
+
+ @Override
+ public final List<UnknownSchemaNode> getUnknownSchemaNodes() {
+ return definition.getUnknownSchemaNodes();
+ }
+
+ @Override
+ public final String getDescription() {
+ return definition.getDescription();
+ }
+
+ @Override
+ public final String getReference() {
+ return definition.getReference();
+ }
+
+ @Override
+ public final String getUnits() {
+ return definition.getUnits();
+ }
+
+ @Override
+ public final Object getDefaultValue() {
+ return definition.getDefaultValue();
+ }
+
+ @Override
+ public final Status getStatus() {
+ return definition.getStatus();
+ }
+
+ @Override
+ public final T getBaseType() {
+ final TypeDefinition<?> base = definition.getBaseType();
+ if (publicType.isInstance(base)) {
+ return publicType.cast(base);
+ } else if (base instanceof ExtendedType) {
+ return createDerived((ExtendedType) base);
+ }
+ throw new IllegalStateException("Unsupported base type.");
+ }
+
+ protected ExtendedType delegate() {
+ return definition;
+ }
+
+ /**
+ *
+ * Creates derived type from supplied ExtendedType, which will implement
+ * proper {@link TypeDefinition} interface.
+ *
+ * @param base Base definition, which does not implement concrete API
+ * @return wrapper which implements proper subinterface of {@link TypeDefinition}.
+ */
+ abstract T createDerived(ExtendedType base);
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.export;
+
+import com.google.common.primitives.UnsignedInteger;
+import java.net.URI;
+import java.util.Date;
+import java.util.List;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.RevisionAwareXPath;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+import org.opendaylight.yangtools.yang.model.api.Status;
+import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
+
+interface Rfc6020ModuleWriter {
+
+ void endNode();
+
+ void startModuleNode(String identifier);
+
+ void startOrganizationNode(String input);
+
+ void startContactNode(String input);
+
+ void startDescriptionNode(String input);
+
+ void startUnitsNode(String input);
+
+ void startYangVersionNode(String input);
+
+ void startNamespaceNode(URI uri);
+
+ void startKeyNode(List<QName> keyList);
+
+ void startPrefixNode(String input);
+
+ void startFeatureNode(QName qName);
+
+ void startExtensionNode(QName qName);
+
+ void startArgumentNode(String input);
+
+ void startStatusNode(Status status);
+
+ void startTypeNode(QName qName);
+
+ void startLeafNode(QName qName);
+
+ void startContainerNode(QName qName);
+
+ void startGroupingNode(QName qName);
+
+ void startRpcNode(QName qName);
+
+ void startInputNode();
+
+ void startOutputNode();
+
+ void startLeafListNode(QName qName);
+
+ void startListNode(QName qName);
+
+ void startChoiceNode(QName qName);
+
+ void startCaseNode(QName qName);
+
+ void startNotificationNode(QName qName);
+
+ void startIdentityNode(QName qName);
+
+ void startBaseNode(QName qName);
+
+ void startTypedefNode(QName qName);
+
+ void startRevisionNode(Date date);
+
+ void startDefaultNode(String string);
+
+ void startMustNode(RevisionAwareXPath xpath);
+
+ void startErrorMessageNode(String input);
+
+ void startErrorAppTagNode(String input);
+
+ void startPatternNode(String regularExpression);
+
+ void startValueNode(Integer integer);
+
+ void startEnumNode(String name);
+
+ void startRequireInstanceNode(boolean require);
+
+ void startPathNode(RevisionAwareXPath revisionAwareXPath);
+
+ void startBitNode(String name);
+
+ void startPositionNode(UnsignedInteger position);
+
+ void startReferenceNode(String input);
+
+ void startRevisionDateNode(Date date);
+
+ void startImportNode(String moduleName);
+
+ void startUsesNode(QName groupingName);
+
+ void startAugmentNode(SchemaPath targetPath);
+
+ void startConfigNode(boolean config);
+
+ void startLengthNode(String lengthString);
+
+ void startMaxElementsNode(Integer max);
+
+ void startMinElementsNode(Integer min);
+
+ void startPresenceNode(boolean presence);
+
+ void startOrderedByNode(String ordering);
+
+ void startRangeNode(String rangeString);
+
+ void startRefineNode(SchemaPath path);
+
+ void startMandatoryNode(boolean mandatory);
+
+ void startAnyxmlNode(QName qName);
+
+ void startUnknownNode(StatementDefinition def);
+
+ void startUnknownNode(StatementDefinition def, String nodeParameter);
+
+ void startFractionDigitsNode(Integer fractionDigits);
+
+ void startYinElementNode(boolean yinElement);
+
+ void startWhenNode(RevisionAwareXPath revisionAwareXPath);
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.export;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Strings;
+import com.google.common.primitives.UnsignedInteger;
+import java.net.URI;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Objects;
+import java.util.Set;
+import javax.annotation.Nullable;
+import javax.annotation.concurrent.NotThreadSafe;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.AnyXmlSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
+import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
+import org.opendaylight.yangtools.yang.model.api.ChoiceNode;
+import org.opendaylight.yangtools.yang.model.api.ConstraintDefinition;
+import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.Deviation;
+import org.opendaylight.yangtools.yang.model.api.DocumentedNode;
+import org.opendaylight.yangtools.yang.model.api.ExtensionDefinition;
+import org.opendaylight.yangtools.yang.model.api.FeatureDefinition;
+import org.opendaylight.yangtools.yang.model.api.GroupingDefinition;
+import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode;
+import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.ModuleImport;
+import org.opendaylight.yangtools.yang.model.api.MustDefinition;
+import org.opendaylight.yangtools.yang.model.api.NotificationDefinition;
+import org.opendaylight.yangtools.yang.model.api.RevisionAwareXPath;
+import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.SchemaNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+import org.opendaylight.yangtools.yang.model.api.Status;
+import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.UsesNode;
+import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.BinaryTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition.Bit;
+import org.opendaylight.yangtools.yang.model.api.type.BooleanTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.DecimalTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.EmptyTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition.EnumPair;
+import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.InstanceIdentifierTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.IntegerTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.LeafrefTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.LengthConstraint;
+import org.opendaylight.yangtools.yang.model.api.type.PatternConstraint;
+import org.opendaylight.yangtools.yang.model.api.type.RangeConstraint;
+import org.opendaylight.yangtools.yang.model.api.type.StringTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.UnsignedIntegerTypeDefinition;
+import org.opendaylight.yangtools.yang.model.util.ExtendedType;
+import org.opendaylight.yangtools.yang.model.util.SchemaNodeUtils;
+
+@Beta
+@NotThreadSafe
+class SchemaContextEmitter {
+
+ private final Rfc6020ModuleWriter writer;
+ private final boolean emitInstantiated;
+ private final boolean emitUses;
+ private final Map<QName, StatementDefinition> extensions;
+
+ SchemaContextEmitter(final Rfc6020ModuleWriter writer, final Map<QName, StatementDefinition> extensions) {
+ this(writer, extensions,false, true);
+ }
+
+ SchemaContextEmitter(final Rfc6020ModuleWriter writer, final Map<QName, StatementDefinition> extensions, final boolean emitInstantiated, final boolean emitUses) {
+ this.writer = Preconditions.checkNotNull(writer);
+ this.emitInstantiated = emitInstantiated;
+ this.emitUses = emitUses;
+ this.extensions = Preconditions.checkNotNull(extensions);
+ }
+
+ static void writeToStatementWriter(final Module module, final SchemaContext ctx, final StatementTextWriter statementWriter) {
+ final Rfc6020ModuleWriter yangSchemaWriter = SchemaToStatementWriterAdaptor.from(statementWriter);
+ final Map<QName, StatementDefinition> extensions = ExtensionStatement.mapFrom(ctx.getExtensions());
+ new SchemaContextEmitter(yangSchemaWriter,extensions).emitModule(module);
+ }
+
+ void emitModule(final Module input) {
+ writer.startModuleNode(input.getName());
+ emitModuleHeader(input);
+ emitLinkageNodes(input);
+ emitMetaNodes(input);
+ emitRevisionNodes(input);
+ emitBodyNodes(input);
+ writer.endNode();
+ }
+
+ private void emitModuleHeader(final Module input) {
+ emitYangVersionNode(input.getYangVersion());
+ emitNamespace(input.getNamespace());
+ emitPrefixNode(input.getPrefix());
+ }
+
+ @SuppressWarnings("unused")
+ private void emitSubmodule(final String input) {
+ /*
+ * FIXME: BUG-2444: Implement submodule export
+ *
+ * submoduleHeaderNodes linkageNodes metaNodes revisionNodes bodyNodes
+ * writer.endNode();
+ */
+ }
+
+ @SuppressWarnings("unused")
+ private void emitSubmoduleHeaderNodes(final Module input) {
+ /*
+ * FIXME: BUG-2444: Implement submodule headers properly
+ *
+ * :yangVersionNode //Optional
+ *
+ * :belongsToNode
+ */
+ }
+
+ private void emitMetaNodes(final Module input) {
+
+ emitOrganizationNode(input.getOrganization()); // FIXME: BUG-2444: Optional
+ emitContact(input.getContact()); // FIXME: BUG-2444: Optional
+ emitDescriptionNode(input.getDescription());
+ emitReferenceNode(input.getReference());
+ }
+
+ private void emitLinkageNodes(final Module input) {
+ for (final ModuleImport importNode : input.getImports()) {
+ emitImport(importNode);
+ }
+ /*
+ * FIXME: BUG-2444: Emit include statements
+ */
+ }
+
+ private void emitRevisionNodes(final Module input) {
+ /*
+ * FIXME: BUG-2444: emit revisions properly, when parsed model will provide enough
+ * information
+ */
+ emitRevision(input.getRevision());
+
+ }
+
+ private void emitBodyNodes(final Module input) {
+
+ for (final ExtensionDefinition extension : input.getExtensionSchemaNodes()) {
+ emitExtension(extension);
+ }
+ for (final FeatureDefinition definition : input.getFeatures()) {
+ emitFeature(definition);
+ }
+ for (final IdentitySchemaNode identity : input.getIdentities()) {
+ emitIdentity(identity);
+ }
+
+ emitDataNodeContainer(input);
+
+ for (final AugmentationSchema augmentation : input.getAugmentations()) {
+ emitAugment(augmentation);
+ }
+ for (final RpcDefinition rpc : input.getRpcs()) {
+ emitRpc(rpc);
+ }
+ for (final NotificationDefinition notification : input.getNotifications()) {
+ emitNotificationNode(notification);
+ }
+ for (final Deviation deviation : input.getDeviations()) {
+ emitDeviation(deviation);
+ }
+
+ }
+
+ private void emitDataNodeContainer(final DataNodeContainer input) {
+ for (final TypeDefinition<?> typedef : input.getTypeDefinitions()) {
+ emitTypedefNode(typedef);
+ }
+ for (final GroupingDefinition grouping : input.getGroupings()) {
+ emitGrouping(grouping);
+ }
+ for (final DataSchemaNode child : input.getChildNodes()) {
+ emitDataSchemaNode(child);
+ }
+ for (final UsesNode usesNode : input.getUses()) {
+ emitUsesNode(usesNode);
+ }
+ }
+
+ private void emitDataSchemaNode(final DataSchemaNode child) {
+ if (!emitInstantiated && (child.isAddedByUses() || child.isAugmenting())) {
+ // We skip instantiated nodes.
+ return;
+ }
+
+ if (child instanceof ContainerSchemaNode) {
+ emitContainer((ContainerSchemaNode) child);
+ } else if (child instanceof LeafSchemaNode) {
+ emitLeaf((LeafSchemaNode) child);
+ } else if (child instanceof LeafListSchemaNode) {
+ emitLeafList((LeafListSchemaNode) child);
+ } else if (child instanceof ListSchemaNode) {
+ emitList((ListSchemaNode) child);
+ } else if (child instanceof ChoiceNode) {
+ emitChoice((ChoiceNode) child);
+ } else if (child instanceof AnyXmlSchemaNode) {
+ emitAnyxml((AnyXmlSchemaNode) child);
+ } else {
+ throw new UnsupportedOperationException("Not supported DataSchemaNode type " + child.getClass());
+ }
+ }
+
+ private void emitYangVersionNode(final String input) {
+ writer.startYangVersionNode(input);
+ writer.endNode();
+ }
+
+ private void emitImport(final ModuleImport importNode) {
+ writer.startImportNode(importNode.getModuleName());
+ emitPrefixNode(importNode.getPrefix());
+ emitRevisionDateNode(importNode.getRevision());
+ writer.endNode();
+ }
+
+ @SuppressWarnings("unused")
+ private void emitInclude(final String input) {
+ /*
+ * FIXME: BUG-2444: Implement proper export of include statements
+ * startIncludeNode(IdentifierHelper.getIdentifier(String :input));
+ *
+ *
+ * :revisionDateNode :writer.endNode();)
+ */
+ }
+
+ private void emitNamespace(final URI uri) {
+ writer.startNamespaceNode(uri);
+ writer.endNode();
+
+ }
+
+ private void emitPrefixNode(final String input) {
+ writer.startPrefixNode(input);
+ writer.endNode();
+
+ }
+
+ @SuppressWarnings("unused")
+ private void emitBelongsTo(final String input) {
+ /*
+ * FIXME: BUG-2444: Implement proper export of belongs-to statements
+ * startIncludeNode(IdentifierHelper.getIdentifier(String :input));
+ *
+ *
+ * :writer.startBelongsToNode(IdentifierHelper.getIdentifier(String
+ * :input));
+ *
+ *
+ * :prefixNode
+ * :writer.endNode();
+ *
+ */
+
+ }
+
+ private void emitOrganizationNode(final String input) {
+ writer.startOrganizationNode(input);
+ writer.endNode();
+
+ }
+
+ private void emitContact(final String input) {
+ writer.startContactNode(input);
+ writer.endNode();
+
+ }
+
+ private void emitDescriptionNode(@Nullable final String input) {
+ if (!Strings.isNullOrEmpty(input)) {
+ writer.startDescriptionNode(input);
+ writer.endNode();
+ }
+ }
+
+ private void emitReferenceNode(@Nullable final String input) {
+ if (!Strings.isNullOrEmpty(input)) {
+ writer.startReferenceNode(input);
+ writer.endNode();
+ }
+ }
+
+ private void emitUnitsNode(@Nullable final String input) {
+ if (!Strings.isNullOrEmpty(input)) {
+ writer.startUnitsNode(input);
+ writer.endNode();
+ }
+ }
+
+ private void emitRevision(final Date date) {
+ writer.startRevisionNode(date);
+
+ //
+ // FIXME: BUG-2444: FIXME: BUG-2444: BUG-2417: descriptionNode //FIXME: BUG-2444: Optional
+ // FIXME: BUG-2444: FIXME: BUG-2444: BUG-2417: referenceNode //FIXME: BUG-2444: Optional
+ writer.endNode();
+
+ }
+
+ private void emitRevisionDateNode(@Nullable final Date date) {
+ if (date != null) {
+ writer.startRevisionDateNode(date);
+ writer.endNode();
+ }
+ }
+
+ private void emitExtension(final ExtensionDefinition extension) {
+ writer.startExtensionNode(extension.getQName());
+ emitArgument(extension.getArgument(),extension.isYinElement());
+ emitStatusNode(extension.getStatus());
+ emitDescriptionNode(extension.getDescription());
+ emitReferenceNode(extension.getReference());
+ emitUnknownStatementNodes(extension.getUnknownSchemaNodes());
+ writer.endNode();
+
+ }
+
+ private void emitArgument(final @Nullable String input, final boolean yinElement) {
+ if (input != null) {
+ writer.startArgumentNode(input);
+ emitYinElement(yinElement);
+ writer.endNode();
+ }
+
+ }
+
+ private void emitYinElement(final boolean yinElement) {
+ writer.startYinElementNode(yinElement);
+ writer.endNode();
+
+ }
+
+ private void emitIdentity(final IdentitySchemaNode identity) {
+ writer.startIdentityNode(identity.getQName());
+ if (identity.getBaseIdentity() != null) {
+ emitBase(identity.getBaseIdentity().getQName());
+ }
+ emitStatusNode(identity.getStatus());
+ emitDescriptionNode(identity.getDescription());
+ emitReferenceNode(identity.getReference());
+ writer.endNode();
+
+ }
+
+ private void emitBase(final QName qName) {
+ writer.startBaseNode(qName);
+ writer.endNode();
+
+ }
+
+ private void emitFeature(final FeatureDefinition definition) {
+ writer.startFeatureNode(definition.getQName());
+
+ // FIXME: BUG-2444: FIXME: BUG-2444: Expose ifFeature *(ifFeatureNode )
+ emitStatusNode(definition.getStatus());
+ emitDescriptionNode(definition.getDescription());
+ emitReferenceNode(definition.getReference());
+ writer.endNode();
+
+ }
+
+ @SuppressWarnings("unused")
+ private void emitIfFeature(final String input) {
+ /*
+ * FIXME: BUG-2444: Implement proper export of include statements
+ * startIncludeNode(IdentifierHelper.getIdentifier(String :input));
+ *
+ */
+ }
+
+ private void emitTypedefNode(final TypeDefinition<?> typedef) {
+ writer.startTypedefNode(typedef.getQName());
+ // Differentiate between derived type and existing type
+ // name.
+ emitTypeNodeDerived(typedef);
+ emitUnitsNode(typedef.getUnits());
+ emitDefaultNode(typedef.getDefaultValue());
+ emitStatusNode(typedef.getStatus());
+ emitDescriptionNode(typedef.getDescription());
+ emitReferenceNode(typedef.getReference());
+ emitUnknownStatementNodes(typedef.getUnknownSchemaNodes());
+ writer.endNode();
+
+ }
+
+ private void emitTypeNode(final SchemaPath parentPath, final TypeDefinition<?> subtype) {
+ final SchemaPath path = subtype.getPath();
+ if (isPrefix(parentPath.getPathFromRoot(), path.getPathFromRoot())) {
+ emitTypeNodeDerived(subtype);
+ } else {
+ emitTypeNodeReferenced(subtype);
+ }
+ }
+
+ private void emitTypeNodeReferenced(final TypeDefinition<?> typeDefinition) {
+ writer.startTypeNode(typeDefinition.getQName());
+ writer.endNode();
+
+ }
+
+ private void emitTypeNodeDerived(final TypeDefinition<?> typeDefinition) {
+ final TypeDefinition<?> baseType;
+ if (typeDefinition.getBaseType() != null) {
+ baseType = typeDefinition.getBaseType();
+ } else {
+ baseType = typeDefinition;
+ }
+ writer.startTypeNode(baseType.getQName());
+ emitTypeBodyNodes(typeDefinition);
+ writer.endNode();
+
+ }
+
+ private void emitTypeBodyNodes(final TypeDefinition<?> typeDef) {
+ if (typeDef instanceof ExtendedType) {
+ emitTypeBodyNodes(NormalizatedDerivedType.from((ExtendedType) typeDef));
+ } else if (typeDef instanceof UnsignedIntegerTypeDefinition) {
+ emitUnsignedIntegerSpecification((UnsignedIntegerTypeDefinition) typeDef);
+ } else if (typeDef instanceof IntegerTypeDefinition) {
+ emitIntegerSpefication((IntegerTypeDefinition) typeDef);
+ } else if (typeDef instanceof DecimalTypeDefinition) {
+ emitDecimal64Specification((DecimalTypeDefinition) typeDef);
+ } else if (typeDef instanceof StringTypeDefinition) {
+ emitStringRestrictions((StringTypeDefinition) typeDef);
+ } else if (typeDef instanceof EnumTypeDefinition) {
+ emitEnumSpecification((EnumTypeDefinition) typeDef);
+ } else if (typeDef instanceof LeafrefTypeDefinition) {
+ emitLeafrefSpecification((LeafrefTypeDefinition) typeDef);
+ } else if (typeDef instanceof IdentityrefTypeDefinition) {
+ emitIdentityrefSpecification((IdentityrefTypeDefinition) typeDef);
+ } else if (typeDef instanceof InstanceIdentifierTypeDefinition) {
+ emitInstanceIdentifierSpecification((InstanceIdentifierTypeDefinition) typeDef);
+ } else if (typeDef instanceof BitsTypeDefinition) {
+ emitBitsSpecification((BitsTypeDefinition) typeDef);
+ } else if (typeDef instanceof UnionTypeDefinition) {
+ emitUnionSpecification((UnionTypeDefinition) typeDef);
+ } else if (typeDef instanceof BinaryTypeDefinition) {
+ // FIXME: BUG-2444: Is this realy NOOP?
+ // should at least support length statement
+ } else if (typeDef instanceof BooleanTypeDefinition || typeDef instanceof EmptyTypeDefinition) {
+ // NOOP
+ } else {
+ throw new IllegalArgumentException("Not supported type " + typeDef.getClass());
+ }
+ }
+
+ private void emitIntegerSpefication(final IntegerTypeDefinition typeDef) {
+ emitRangeNodeOptional(typeDef.getRangeConstraints());
+ }
+
+ private void emitUnsignedIntegerSpecification(final UnsignedIntegerTypeDefinition typeDef) {
+ emitRangeNodeOptional(typeDef.getRangeConstraints());
+
+ }
+
+ private void emitRangeNodeOptional(final List<RangeConstraint> list) {
+ // FIXME: BUG-2444: Wrong decomposition in API, should be LenghtConstraint
+ // which contains ranges.
+ if (!list.isEmpty()) {
+ writer.startRangeNode(toRangeString(list));
+ final RangeConstraint first = list.iterator().next();
+ emitErrorMessageNode(first.getErrorMessage());
+ emitErrorAppTagNode(first.getErrorAppTag());
+ emitDescriptionNode(first.getDescription());
+ emitReferenceNode(first.getReference());
+ writer.endNode();
+ }
+
+ }
+
+ private void emitDecimal64Specification(final DecimalTypeDefinition typeDefinition) {
+ emitFranctionDigitsNode(typeDefinition.getFractionDigits());
+ emitRangeNodeOptional(typeDefinition.getRangeConstraints());
+
+ }
+
+ private void emitFranctionDigitsNode(final Integer fractionDigits) {
+ writer.startFractionDigitsNode(fractionDigits);
+ writer.endNode();
+ }
+
+ private void emitStringRestrictions(final StringTypeDefinition typeDef) {
+
+ // FIXME: BUG-2444: Wrong decomposition in API, should be LenghtConstraint
+ // which contains ranges.
+ emitLength(typeDef.getLengthConstraints());
+
+ for (final PatternConstraint pattern : typeDef.getPatternConstraints()) {
+ emitPatternNode(pattern);
+ }
+
+ }
+
+ private void emitLength(final List<LengthConstraint> list) {
+ if (!list.isEmpty()) {
+ writer.startLengthNode(toLengthString(list));
+ // FIXME: BUG-2444: Workaround for incorrect decomposition in API
+ final LengthConstraint first = list.iterator().next();
+ emitErrorMessageNode(first.getErrorMessage());
+ emitErrorAppTagNode(first.getErrorAppTag());
+ emitDescriptionNode(first.getDescription());
+ emitReferenceNode(first.getReference());
+ writer.endNode();
+ }
+
+ }
+
+ private String toLengthString(final List<LengthConstraint> list) {
+ final StringBuilder lengthStr = new StringBuilder();
+ final Iterator<LengthConstraint> constIt = list.iterator();
+ while (constIt.hasNext()) {
+ final LengthConstraint current = constIt.next();
+ if (current.getMin() == current.getMax()) {
+ lengthStr.append(current.getMin());
+ } else {
+ lengthStr.append(current.getMin());
+ lengthStr.append("..");
+ lengthStr.append(current.getMax());
+ }
+ if (constIt.hasNext()) {
+ lengthStr.append("|");
+ }
+ }
+ return lengthStr.toString();
+ }
+
+ private String toRangeString(final List<RangeConstraint> list) {
+ final StringBuilder lengthStr = new StringBuilder();
+ final Iterator<RangeConstraint> constIt = list.iterator();
+ while (constIt.hasNext()) {
+ final RangeConstraint current = constIt.next();
+ if (current.getMin() == current.getMax()) {
+ lengthStr.append(current.getMin());
+ } else {
+ lengthStr.append(current.getMin());
+ lengthStr.append("..");
+ lengthStr.append(current.getMax());
+ }
+ if (constIt.hasNext()) {
+ lengthStr.append("|");
+ }
+ }
+ return lengthStr.toString();
+ }
+
+ private void emitPatternNode(final PatternConstraint pattern) {
+ writer.startPatternNode(pattern.getRegularExpression());
+ emitErrorMessageNode(pattern.getErrorMessage()); // FIXME: BUG-2444: Optional
+ emitErrorAppTagNode(pattern.getErrorAppTag()); // FIXME: BUG-2444: Optional
+ emitDescriptionNode(pattern.getDescription());
+ emitReferenceNode(pattern.getReference()); // FIXME: BUG-2444: Optional
+ writer.endNode();
+ }
+
+ private void emitDefaultNode(@Nullable final Object object) {
+ if (object != null) {
+ writer.startDefaultNode(object.toString());
+ writer.endNode();
+ }
+
+ }
+
+ private void emitEnumSpecification(final EnumTypeDefinition typeDefinition) {
+ for (final EnumPair enumValue : typeDefinition.getValues()) {
+ emitEnumNode(enumValue);
+ }
+ }
+
+ private void emitEnumNode(final EnumPair enumValue) {
+ writer.startEnumNode(enumValue.getName());
+ emitValueNode(enumValue.getValue());
+ emitStatusNode(enumValue.getStatus());
+ emitDescriptionNode(enumValue.getDescription());
+ emitReferenceNode(enumValue.getReference());
+ writer.endNode();
+ }
+
+ private void emitLeafrefSpecification(final LeafrefTypeDefinition typeDefinition) {
+ emitPathNode(typeDefinition.getPathStatement());
+ // FIXME: BUG-2444: requireInstanceNode /Optional removed with (RFC6020 - Errata ID
+ // 2949)
+ // Added in Yang 1.1
+ }
+
+ private void emitPathNode(final RevisionAwareXPath revisionAwareXPath) {
+ writer.startPathNode(revisionAwareXPath);
+ writer.endNode();
+ }
+
+ private void emitRequireInstanceNode(final boolean require) {
+ writer.startRequireInstanceNode(require);
+ writer.endNode();
+ }
+
+ private void emitInstanceIdentifierSpecification(final InstanceIdentifierTypeDefinition typeDefinition) {
+ emitRequireInstanceNode(typeDefinition.requireInstance());
+ }
+
+ private void emitIdentityrefSpecification(final IdentityrefTypeDefinition typeDefinition) {
+ emitBase(typeDefinition.getQName());
+ }
+
+ private void emitUnionSpecification(final UnionTypeDefinition typeDefinition) {
+ for (final TypeDefinition<?> subtype : typeDefinition.getTypes()) {
+ // FIXME: BUG-2444: What if we have locally modified types here?
+ // is solution to look-up in schema path?
+ emitTypeNode(typeDefinition.getPath(), subtype);
+ }
+ }
+
+ private void emitBitsSpecification(final BitsTypeDefinition typeDefinition) {
+ for (final Bit bit : typeDefinition.getBits()) {
+ emitBit(bit);
+ }
+ }
+
+ private void emitBit(final Bit bit) {
+ writer.startBitNode(bit.getName());
+ emitPositionNode(bit.getPosition());
+ emitStatusNode(bit.getStatus());
+ emitDescriptionNode(bit.getDescription());
+ emitReferenceNode(bit.getReference());
+ writer.endNode();
+ }
+
+ private void emitPositionNode(@Nullable final Long position) {
+ if (position != null) {
+ writer.startPositionNode(UnsignedInteger.valueOf(position));
+ writer.endNode();
+ }
+ }
+
+ private void emitStatusNode(@Nullable final Status status) {
+ if (status != null) {
+ writer.startStatusNode(status);
+ writer.endNode();
+ }
+ }
+
+ private void emitConfigNode(final boolean config) {
+ writer.startConfigNode(config);
+ writer.endNode();
+ }
+
+ private void emitMandatoryNode(final boolean mandatory) {
+ writer.startMandatoryNode(mandatory);
+ writer.endNode();
+ }
+
+ private void emitPresenceNode(final boolean presence) {
+ writer.startPresenceNode(presence);
+ writer.endNode();
+ }
+
+ private void emitOrderedBy(final boolean userOrdered) {
+ if (userOrdered) {
+ writer.startOrderedByNode("user");
+ } else {
+ writer.startOrderedByNode("system");
+ }
+ writer.endNode();
+ }
+
+ private void emitMust(@Nullable final MustDefinition mustCondition) {
+ if(mustCondition != null && mustCondition.getXpath() != null) {
+ writer.startMustNode(mustCondition.getXpath());
+ emitErrorMessageNode(mustCondition.getErrorMessage());
+ emitErrorAppTagNode(mustCondition.getErrorAppTag());
+ emitDescriptionNode(mustCondition.getDescription());
+ emitReferenceNode(mustCondition.getReference());
+ writer.endNode();
+ }
+
+ }
+
+ private void emitErrorMessageNode(@Nullable final String input) {
+ if (input != null && !input.isEmpty()) {
+ writer.startErrorMessageNode(input);
+ writer.endNode();
+ }
+ }
+
+ private void emitErrorAppTagNode(final String input) {
+ if (input != null && !input.isEmpty()) {
+ writer.startErrorAppTagNode(input);
+ writer.endNode();
+ }
+ }
+
+ private void emitMinElementsNode(final Integer min) {
+ if (min != null) {
+ writer.startMinElementsNode(min);
+ writer.endNode();
+ }
+ }
+
+ private void emitMaxElementsNode(final Integer max) {
+ if (max != null) {
+ writer.startMaxElementsNode(max);
+ writer.endNode();
+ }
+ }
+
+ private void emitValueNode(@Nullable final Integer value) {
+ if (value != null) {
+ writer.startValueNode(value);
+ writer.endNode();
+ }
+ }
+
+ private void emitDocumentedNode(final DocumentedNode input) {
+ emitStatusNode(input.getStatus());
+ emitDescriptionNode(input.getDescription());
+ emitReferenceNode(input.getReference());
+ }
+
+ private void emitGrouping(final GroupingDefinition grouping) {
+ writer.startGroupingNode(grouping.getQName());
+ emitDocumentedNode(grouping);
+ emitDataNodeContainer(grouping);
+ emitUnknownStatementNodes(grouping.getUnknownSchemaNodes());
+ writer.endNode();
+
+ }
+
+ private void emitContainer(final ContainerSchemaNode child) {
+ writer.startContainerNode(child.getQName());
+
+ //
+
+ emitConstraints(child.getConstraints());
+ // FIXME: BUG-2444: whenNode //:Optional
+ // FIXME: BUG-2444: *(ifFeatureNode )
+ emitMustNodes(child.getConstraints().getMustConstraints());
+ emitPresenceNode(child.isPresenceContainer());
+ emitConfigNode(child.isConfiguration());
+ emitDocumentedNode(child);
+ emitDataNodeContainer(child);
+ emitUnknownStatementNodes(child.getUnknownSchemaNodes());
+ writer.endNode();
+
+ }
+
+ private void emitConstraints(final ConstraintDefinition constraints) {
+ emitWhen(constraints.getWhenCondition());
+ for (final MustDefinition mustCondition : constraints.getMustConstraints()) {
+ emitMust(mustCondition);
+ }
+
+ }
+
+ private void emitLeaf(final LeafSchemaNode child) {
+ writer.startLeafNode(child.getQName());
+ emitWhen(child.getConstraints().getWhenCondition());
+ // FIXME: BUG-2444: *(ifFeatureNode )
+ emitTypeNode(child.getPath(), child.getType());
+ emitUnitsNode(child.getUnits());
+ emitMustNodes(child.getConstraints().getMustConstraints());
+ emitDefaultNode(child.getDefault());
+ emitConfigNode(child.isConfiguration());
+ emitMandatoryNode(child.getConstraints().isMandatory());
+ emitDocumentedNode(child);
+ emitUnknownStatementNodes(child.getUnknownSchemaNodes());
+ writer.endNode();
+
+ }
+
+ private void emitLeafList(final LeafListSchemaNode child) {
+ writer.startLeafListNode(child.getQName());
+
+ emitWhen(child.getConstraints().getWhenCondition());
+ // FIXME: BUG-2444: *(ifFeatureNode )
+ emitTypeNode(child.getPath(), child.getType());
+ // FIXME: BUG-2444: unitsNode /Optional
+ emitMustNodes(child.getConstraints().getMustConstraints());
+ emitConfigNode(child.isConfiguration());
+
+ emitMinElementsNode(child.getConstraints().getMinElements());
+ emitMaxElementsNode(child.getConstraints().getMaxElements());
+ emitOrderedBy(child.isUserOrdered());
+ emitDocumentedNode(child);
+ emitUnknownStatementNodes(child.getUnknownSchemaNodes());
+ writer.endNode();
+
+ }
+
+ private void emitList(final ListSchemaNode child) {
+ writer.startListNode(child.getQName());
+ emitWhen(child.getConstraints().getWhenCondition());
+
+ // FIXME: BUG-2444: *(ifFeatureNode )
+ emitMustNodes(child.getConstraints().getMustConstraints());
+ emitKey(child.getKeyDefinition());
+ // FIXME: BUG-2444: *(uniqueNode )
+ emitConfigNode(child.isConfiguration());
+ emitMinElementsNode(child.getConstraints().getMinElements());
+ emitMaxElementsNode(child.getConstraints().getMaxElements());
+ emitOrderedBy(child.isUserOrdered());
+ emitDocumentedNode(child);
+ emitDataNodeContainer(child);
+ emitUnknownStatementNodes(child.getUnknownSchemaNodes());
+ writer.endNode();
+
+ }
+
+ private void emitMustNodes(final Set<MustDefinition> mustConstraints) {
+ for (final MustDefinition must : mustConstraints) {
+ emitMust(must);
+ }
+ }
+
+ private void emitKey(final List<QName> keyList) {
+ if (keyList != null && !keyList.isEmpty()) {
+ writer.startKeyNode(keyList);
+ writer.endNode();
+ }
+ }
+
+ @SuppressWarnings("unused")
+ private void emitUnique(final String input) {
+ // FIXME: BUG-2444: writer.startUniqueNode(uniqueArgStr)); Nodeend
+
+ }
+
+ private void emitChoice(final ChoiceNode choice) {
+ writer.startChoiceNode(choice.getQName());
+ emitWhen(choice.getConstraints().getWhenCondition());
+ // FIXME: BUG-2444: *(ifFeatureNode )
+ // FIXME: BUG-2444: defaultNode //Optional
+ emitConfigNode(choice.isConfiguration());
+ emitMandatoryNode(choice.getConstraints().isMandatory());
+ emitDocumentedNode(choice);
+ for (final ChoiceCaseNode caze : choice.getCases()) {
+ // TODO: emit short case?
+ emitCaseNode(caze);
+ }
+ emitUnknownStatementNodes(choice.getUnknownSchemaNodes());
+ writer.endNode();
+ }
+
+ private void emitCaseNode(final ChoiceCaseNode caze) {
+ if (!emitInstantiated && caze.isAugmenting()) {
+ return;
+ }
+ writer.startCaseNode(caze.getQName());
+ emitWhen(caze.getConstraints().getWhenCondition());
+ // FIXME: BUG-2444: *(ifFeatureNode )
+ emitDocumentedNode(caze);
+ emitDataNodeContainer(caze);
+ emitUnknownStatementNodes(caze.getUnknownSchemaNodes());
+ writer.endNode();
+
+ }
+
+ private void emitAnyxml(final AnyXmlSchemaNode child) {
+ writer.startAnyxmlNode(child.getQName());
+
+ emitWhen(child.getConstraints().getWhenCondition());
+ // FIXME: BUG-2444: *(ifFeatureNode )
+ emitMustNodes(child.getConstraints().getMustConstraints());
+ emitConfigNode(child.isConfiguration());
+ emitMandatoryNode(child.getConstraints().isMandatory());
+ emitDocumentedNode(child);
+ emitUnknownStatementNodes(child.getUnknownSchemaNodes());
+ writer.endNode();
+
+ }
+
+ private void emitUsesNode(final UsesNode usesNode) {
+ if (emitUses && !usesNode.isAddedByUses() && !usesNode.isAugmenting()) {
+ writer.startUsesNode(usesNode.getGroupingPath().getLastComponent());
+ /*
+ * FIXME: BUG-2444:
+ * whenNode /
+ * *(ifFeatureNode )
+ * statusNode // Optional F
+ * : descriptionNode // Optional
+ * referenceNode // Optional
+ */
+ for (final Entry<SchemaPath, SchemaNode> refine : usesNode.getRefines().entrySet()) {
+ emitRefine(refine);
+ }
+ for (final AugmentationSchema aug : usesNode.getAugmentations()) {
+ emitUsesAugmentNode(aug);
+ }
+ writer.endNode();
+ }
+ }
+
+ private void emitRefine(final Entry<SchemaPath, SchemaNode> refine) {
+ final SchemaPath path = refine.getKey();
+ final SchemaNode value = refine.getValue();
+ writer.startRefineNode(path);
+
+ if (value instanceof LeafSchemaNode) {
+ emitRefineLeafNodes((LeafSchemaNode) value);
+ } else if (value instanceof LeafListSchemaNode) {
+ emitRefineLeafListNodes((LeafListSchemaNode) value);
+ } else if (value instanceof ListSchemaNode) {
+ emitRefineListNodes((ListSchemaNode) value);
+ } else if (value instanceof ChoiceNode) {
+ emitRefineChoiceNodes((ChoiceNode) value);
+ } else if (value instanceof ChoiceCaseNode) {
+ emitRefineCaseNodes((ChoiceCaseNode) value);
+ } else if (value instanceof ContainerSchemaNode) {
+ emitRefineContainerNodes((ContainerSchemaNode) value);
+ } else if (value instanceof AnyXmlSchemaNode) {
+ emitRefineAnyxmlNodes((AnyXmlSchemaNode) value);
+ }
+ writer.endNode();
+
+ }
+
+ private <T extends SchemaNode> T getOriginalChecked(final T value) {
+ final Optional<SchemaNode> original = SchemaNodeUtils.getOriginalIfPossible(value);
+ Preconditions.checkArgument(original.isPresent(), "Original unmodified version of node is not present.");
+ @SuppressWarnings("unchecked")
+ final T ret = (T) original.get();
+ return ret;
+ }
+
+ private void emitDocumentedNodeRefine(final DocumentedNode original, final DocumentedNode value) {
+ if (Objects.deepEquals(original.getDescription(), value.getDescription())) {
+ emitDescriptionNode(value.getDescription());
+ }
+ if (Objects.deepEquals(original.getReference(), value.getReference())) {
+ emitReferenceNode(value.getReference());
+ }
+ }
+
+ private void emitRefineContainerNodes(final ContainerSchemaNode value) {
+ final ContainerSchemaNode original = getOriginalChecked(value);
+
+ // emitMustNodes(child.getConstraints().getMustConstraints());
+ if (Objects.deepEquals(original.isPresenceContainer(), value.isPresenceContainer())) {
+ emitPresenceNode(value.isPresenceContainer());
+ }
+ if (Objects.deepEquals(original.isConfiguration(), value.isConfiguration())) {
+ emitConfigNode(value.isConfiguration());
+ }
+ emitDocumentedNodeRefine(original, value);
+
+ }
+
+ private void emitRefineLeafNodes(final LeafSchemaNode value) {
+ final LeafSchemaNode original = getOriginalChecked(value);
+
+ // emitMustNodes(child.getConstraints().getMustConstraints());
+ if (Objects.deepEquals(original.getDefault(), value.getDefault())) {
+ emitDefaultNode(value.getDefault());
+ }
+ if (Objects.deepEquals(original.isConfiguration(), value.isConfiguration())) {
+ emitConfigNode(value.isConfiguration());
+ }
+ emitDocumentedNodeRefine(original, value);
+ if (Objects.deepEquals(original.getConstraints().isMandatory(), value.getConstraints().isMandatory())) {
+ emitMandatoryNode(value.getConstraints().isMandatory());
+ }
+
+ }
+
+ private void emitRefineLeafListNodes(final LeafListSchemaNode value) {
+ final LeafListSchemaNode original = getOriginalChecked(value);
+
+ // emitMustNodes(child.getConstraints().getMustConstraints());
+ if (Objects.deepEquals(original.isConfiguration(), value.isConfiguration())) {
+ emitConfigNode(value.isConfiguration());
+ }
+ if (Objects.deepEquals(original.getConstraints().getMinElements(), value.getConstraints().getMinElements())) {
+ emitMinElementsNode(value.getConstraints().getMinElements());
+ }
+ if (Objects.deepEquals(original.getConstraints().getMaxElements(), value.getConstraints().getMaxElements())) {
+ emitMaxElementsNode(value.getConstraints().getMaxElements());
+ }
+ emitDocumentedNodeRefine(original, value);
+
+ }
+
+ private void emitRefineListNodes(final ListSchemaNode value) {
+ final ListSchemaNode original = getOriginalChecked(value);
+
+ // emitMustNodes(child.getConstraints().getMustConstraints());
+ if (Objects.deepEquals(original.isConfiguration(), value.isConfiguration())) {
+ emitConfigNode(value.isConfiguration());
+ }
+ if (Objects.deepEquals(original.getConstraints().getMinElements(), value.getConstraints().getMinElements())) {
+ emitMinElementsNode(value.getConstraints().getMinElements());
+ }
+ if (Objects.deepEquals(original.getConstraints().getMaxElements(), value.getConstraints().getMaxElements())) {
+ emitMaxElementsNode(value.getConstraints().getMaxElements());
+ }
+ emitDocumentedNodeRefine(original, value);
+
+ }
+
+ private void emitRefineChoiceNodes(final ChoiceNode value) {
+ final ChoiceNode original = getOriginalChecked(value);
+
+ // FIXME: BUG-2444: defaultNode //FIXME: BUG-2444: Optional
+ if (Objects.deepEquals(original.isConfiguration(), value.isConfiguration())) {
+ emitConfigNode(value.isConfiguration());
+ }
+ if (Objects.deepEquals(original.getConstraints().isMandatory(), value.getConstraints().isMandatory())) {
+ emitMandatoryNode(value.getConstraints().isMandatory());
+ }
+ emitDocumentedNodeRefine(original, value);
+
+ }
+
+ private void emitRefineCaseNodes(final ChoiceCaseNode value) {
+ final ChoiceCaseNode original = getOriginalChecked(value);
+ emitDocumentedNodeRefine(original, value);
+
+ }
+
+ private void emitRefineAnyxmlNodes(final AnyXmlSchemaNode value) {
+ final AnyXmlSchemaNode original = getOriginalChecked(value);
+
+ // FIXME: BUG-2444: emitMustNodes(child.getConstraints().getMustConstraints());
+ if (Objects.deepEquals(original.isConfiguration(), value.isConfiguration())) {
+ emitConfigNode(value.isConfiguration());
+ }
+ if (Objects.deepEquals(original.getConstraints().isMandatory(), value.getConstraints().isMandatory())) {
+ emitMandatoryNode(value.getConstraints().isMandatory());
+ }
+ emitDocumentedNodeRefine(original, value);
+
+ }
+
+ private void emitUsesAugmentNode(final AugmentationSchema aug) {
+ /**
+ * differs only in location in schema, otherwise currently (as of
+ * RFC6020) it is same, so we could freely reuse path.
+ */
+ emitAugment(aug);
+ }
+
+ private void emitAugment(final AugmentationSchema augmentation) {
+ writer.startAugmentNode(augmentation.getTargetPath());
+ // FIXME: BUG-2444: whenNode //Optional
+ // FIXME: BUG-2444: *(ifFeatureNode )
+
+ emitStatusNode(augmentation.getStatus());
+ emitDescriptionNode(augmentation.getDescription());
+ emitReferenceNode(augmentation.getReference());
+ for(final UsesNode uses: augmentation.getUses()) {
+ emitUsesNode(uses);
+ }
+
+ for (final DataSchemaNode childNode : augmentation.getChildNodes()) {
+ if (childNode instanceof ChoiceCaseNode) {
+ emitCaseNode((ChoiceCaseNode) childNode);
+ } else {
+ emitDataSchemaNode(childNode);
+ }
+ }
+ emitUnknownStatementNodes(augmentation.getUnknownSchemaNodes());
+ writer.endNode();
+ }
+
+ private void emitUnknownStatementNodes(final List<UnknownSchemaNode> unknownNodes) {
+ for (final UnknownSchemaNode unknonwnNode : unknownNodes) {
+ emitUnknownStatementNode(unknonwnNode);
+ }
+ }
+
+ private void emitUnknownStatementNode(final UnknownSchemaNode node) {
+ final StatementDefinition def = getStatementChecked(node.getNodeType());
+ if (def.getArgumentName() == null) {
+ writer.startUnknownNode(def);
+ } else {
+ writer.startUnknownNode(def, node.getNodeParameter());
+ }
+ emitUnknownStatementNodes(node.getUnknownSchemaNodes());
+ writer.endNode();
+ }
+
+ private StatementDefinition getStatementChecked(final QName nodeType) {
+ final StatementDefinition ret = extensions.get(nodeType);
+ Preconditions.checkArgument(ret != null, "Unknown extension %s used during export.",nodeType);
+ return ret;
+ }
+
+ private void emitWhen(final RevisionAwareXPath revisionAwareXPath) {
+ if(revisionAwareXPath != null) {
+ writer.startWhenNode(revisionAwareXPath);
+ writer.endNode();
+ }
+ // FIXME: BUG-2444: descriptionNode //FIXME: BUG-2444: Optional
+ // FIXME: BUG-2444: referenceNode //FIXME: BUG-2444: Optional
+ // FIXME: BUG-2444: writer.endNode();)
+
+ }
+
+ private void emitRpc(final RpcDefinition rpc) {
+ writer.startRpcNode(rpc.getQName());
+ // FIXME: BUG-2444: *(ifFeatureNode )
+ emitStatusNode(rpc.getStatus());
+ emitDescriptionNode(rpc.getDescription());
+ emitReferenceNode(rpc.getReference());
+
+ for(final TypeDefinition<?> typedef : rpc.getTypeDefinitions()) {
+ emitTypedefNode(typedef);
+ }
+ for(final GroupingDefinition grouping : rpc.getGroupings()) {
+ emitGrouping(grouping);
+ }
+ emitInput(rpc.getInput());
+ emitOutput(rpc.getOutput());
+ emitUnknownStatementNodes(rpc.getUnknownSchemaNodes());
+ writer.endNode();
+
+ }
+
+ private void emitInput(@Nullable final ContainerSchemaNode input) {
+ if (input != null) {
+ writer.startInputNode();
+ emitDataNodeContainer(input);
+ emitUnknownStatementNodes(input.getUnknownSchemaNodes());
+ writer.endNode();
+ }
+
+ }
+
+ private void emitOutput(@Nullable final ContainerSchemaNode input) {
+ if (input != null) {
+ writer.startOutputNode();
+ emitDataNodeContainer(input);
+ emitUnknownStatementNodes(input.getUnknownSchemaNodes());
+ writer.endNode();
+ }
+
+ }
+
+ private void emitNotificationNode(final NotificationDefinition notification) {
+ writer.startNotificationNode(notification.getQName());
+ // FIXME: BUG-2444: *(ifFeatureNode )
+ emitDocumentedNode(notification);
+ emitDataNodeContainer(notification);
+ emitUnknownStatementNodes(notification.getUnknownSchemaNodes());
+ writer.endNode();
+
+ }
+
+
+ //FIXME: Probably should be moved to utils bundle.
+ private static <T> boolean isPrefix(final Iterable<T> prefix, final Iterable<T> other) {
+ final Iterator<T> prefixIt = prefix.iterator();
+ final Iterator<T> otherIt = other.iterator();
+ while(prefixIt.hasNext()) {
+ if(!otherIt.hasNext()) {
+ return false;
+ }
+ if(!Objects.deepEquals(prefixIt.next(), otherIt.next())) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private void emitDeviation(final Deviation deviation) {
+ /*
+ * FIXME: BUG-2444: Deviation is not modeled properly and we are loosing lot of
+ * information in order to export it properly
+ *
+ * writer.startDeviationNode(deviation.getTargetPath());
+ *
+ * :descriptionNode //:Optional
+ *
+ *
+ * emitReferenceNode(deviation.getReference());
+ * :(deviateNotSupportedNode :1*(deviateAddNode :deviateReplaceNode
+ * :deviateDeleteNode)) :writer.endNode();
+ */
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.export;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Preconditions;
+import com.google.common.primitives.UnsignedInteger;
+import java.net.URI;
+import java.util.Date;
+import java.util.List;
+import javax.annotation.concurrent.NotThreadSafe;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil;
+import org.opendaylight.yangtools.yang.model.api.RevisionAwareXPath;
+import org.opendaylight.yangtools.yang.model.api.Rfc6020Mapping;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+import org.opendaylight.yangtools.yang.model.api.Status;
+import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
+
+@Beta
+@NotThreadSafe
+final class SchemaToStatementWriterAdaptor implements Rfc6020ModuleWriter {
+
+ private final StatementTextWriter writer;
+
+ private SchemaToStatementWriterAdaptor(final StatementTextWriter writer) {
+ this.writer = Preconditions.checkNotNull(writer);
+ }
+
+ public static final Rfc6020ModuleWriter from(final StatementTextWriter writer) {
+ return new SchemaToStatementWriterAdaptor(writer);
+ }
+
+ @Override
+ public void endNode() {
+ writer.endStatement();
+ }
+
+ @Override
+ public void startModuleNode(final String identifier) {
+ writer.startStatement(Rfc6020Mapping.Module);
+ writer.writeArgument(identifier);
+ }
+
+ @Override
+ public void startOrganizationNode(final String input) {
+ writer.startStatement(Rfc6020Mapping.Organization);
+ writer.writeArgument(input);
+ }
+
+ @Override
+ public void startContactNode(final String input) {
+ writer.startStatement(Rfc6020Mapping.Contact);
+ writer.writeArgument(input);
+ }
+
+ @Override
+ public void startDescriptionNode(final String input) {
+ writer.startStatement(Rfc6020Mapping.Description);
+ writer.writeArgument(input);
+ }
+
+ @Override
+ public void startReferenceNode(final String input) {
+ writer.startStatement(Rfc6020Mapping.Reference);
+ writer.writeArgument(input);
+ }
+
+ @Override
+ public void startUnitsNode(final String input) {
+ writer.startStatement(Rfc6020Mapping.Units);
+ writer.writeArgument(input);
+ }
+
+ @Override
+ public void startYangVersionNode(final String input) {
+ writer.startStatement(Rfc6020Mapping.YangVersion);
+ writer.writeArgument(input);
+ }
+
+ @Override
+ public void startNamespaceNode(final URI uri) {
+ writer.startStatement(Rfc6020Mapping.Namespace);
+ writer.writeArgument(uri.toString());
+ }
+
+ @Override
+ public void startKeyNode(final List<QName> keyList) {
+ writer.startStatement(Rfc6020Mapping.Key);
+ final StringBuilder keyStr = new StringBuilder();
+ for (final QName item : keyList) {
+ keyStr.append(item.getLocalName());
+ }
+ writer.writeArgument(keyStr.toString());
+ }
+
+ @Override
+ public void startPrefixNode(final String input) {
+ writer.startStatement(Rfc6020Mapping.Prefix);
+ writer.writeArgument(input);
+ }
+
+ @Override
+ public void startFeatureNode(final QName qName) {
+ writer.startStatement(Rfc6020Mapping.Feature);
+ writer.writeArgument(qName);
+ }
+
+ @Override
+ public void startExtensionNode(final QName qName) {
+ writer.startStatement(Rfc6020Mapping.Extension);
+ writer.writeArgument(qName);
+ }
+
+ @Override
+ public void startArgumentNode(final String input) {
+ writer.startStatement(Rfc6020Mapping.Argument);
+ writer.writeArgument(input);
+ }
+
+ @Override
+ public void startStatusNode(final Status status) {
+ writer.startStatement(Rfc6020Mapping.Status);
+ writer.writeArgument(status.toString().toLowerCase());
+ }
+
+ @Override
+ public void startTypeNode(final QName qName) {
+ writer.startStatement(Rfc6020Mapping.Type);
+ writer.writeArgument(qName);
+ }
+
+ @Override
+ public void startLeafNode(final QName qName) {
+ writer.startStatement(Rfc6020Mapping.Leaf);
+ writer.writeArgument(qName);
+ }
+
+ @Override
+ public void startContainerNode(final QName qName) {
+ writer.startStatement(Rfc6020Mapping.Container);
+ writer.writeArgument(qName);
+ }
+
+ @Override
+ public void startGroupingNode(final QName qName) {
+ writer.startStatement(Rfc6020Mapping.Grouping);
+ writer.writeArgument(qName);
+ }
+
+ @Override
+ public void startRpcNode(final QName qName) {
+ writer.startStatement(Rfc6020Mapping.Rpc);
+ writer.writeArgument(qName);
+ }
+
+ @Override
+ public void startInputNode() {
+ writer.startStatement(Rfc6020Mapping.Input);
+ }
+
+ @Override
+ public void startOutputNode() {
+ writer.startStatement(Rfc6020Mapping.Output);
+ }
+
+ @Override
+ public void startLeafListNode(final QName qName) {
+ writer.startStatement(Rfc6020Mapping.LeafList);
+ writer.writeArgument(qName);
+ }
+
+ @Override
+ public void startListNode(final QName qName) {
+ writer.startStatement(Rfc6020Mapping.List);
+ writer.writeArgument(qName);
+ }
+
+ @Override
+ public void startChoiceNode(final QName qName) {
+ writer.startStatement(Rfc6020Mapping.Choice);
+ writer.writeArgument(qName);
+ }
+
+ @Override
+ public void startCaseNode(final QName qName) {
+ writer.startStatement(Rfc6020Mapping.Case);
+ writer.writeArgument(qName);
+ }
+
+ @Override
+ public void startNotificationNode(final QName qName) {
+ writer.startStatement(Rfc6020Mapping.Notification);
+ writer.writeArgument(qName);
+ }
+
+ @Override
+ public void startIdentityNode(final QName qName) {
+ writer.startStatement(Rfc6020Mapping.Identity);
+ writer.writeArgument(qName);
+ }
+
+ @Override
+ public void startBaseNode(final QName qName) {
+ writer.startStatement(Rfc6020Mapping.Base);
+ writer.writeArgument(qName);
+ }
+
+ @Override
+ public void startTypedefNode(final QName qName) {
+ writer.startStatement(Rfc6020Mapping.Typedef);
+ writer.writeArgument(qName);
+ }
+
+ @Override
+ public void startRevisionNode(final Date date) {
+ writer.startStatement(Rfc6020Mapping.Revision);
+ writer.writeArgument(SimpleDateFormatUtil.getRevisionFormat().format(date));
+ }
+
+ @Override
+ public void startDefaultNode(final String string) {
+ writer.startStatement(Rfc6020Mapping.Default);
+ writer.writeArgument(string);
+ }
+
+ @Override
+ public void startMustNode(final RevisionAwareXPath xpath) {
+ writer.startStatement(Rfc6020Mapping.Must);
+ writer.writeArgument(xpath);
+ }
+
+ @Override
+ public void startErrorMessageNode(final String input) {
+ writer.startStatement(Rfc6020Mapping.ErrorMessage);
+ writer.writeArgument(input);
+ }
+
+ @Override
+ public void startErrorAppTagNode(final String input) {
+ writer.startStatement(Rfc6020Mapping.ErrorAppTag);
+ writer.writeArgument(input);
+ }
+
+ @Override
+ public void startPatternNode(final String regularExpression) {
+ writer.startStatement(Rfc6020Mapping.Pattern);
+ writer.writeArgument(regularExpression);
+ }
+
+ @Override
+ public void startValueNode(final Integer integer) {
+ writer.startStatement(Rfc6020Mapping.Value);
+ writer.writeArgument(integer.toString());
+ }
+
+ @Override
+ public void startEnumNode(final String name) {
+ writer.startStatement(Rfc6020Mapping.Enum);
+ writer.writeArgument(name);
+ }
+
+ @Override
+ public void startRequireInstanceNode(final boolean require) {
+ writer.startStatement(Rfc6020Mapping.RequireInstance);
+ writer.writeArgument(Boolean.toString(require));
+ }
+
+ @Override
+ public void startPathNode(final RevisionAwareXPath revisionAwareXPath) {
+ writer.startStatement(Rfc6020Mapping.Path);
+ writer.writeArgument(revisionAwareXPath);
+ }
+
+ @Override
+ public void startBitNode(final String name) {
+ writer.startStatement(Rfc6020Mapping.Bit);
+ writer.writeArgument(name);
+ }
+
+ @Override
+ public void startPositionNode(final UnsignedInteger position) {
+ writer.startStatement(Rfc6020Mapping.Position);
+ writer.writeArgument(position.toString());
+ }
+
+ @Override
+ public void startImportNode(final String moduleName) {
+ writer.startStatement(Rfc6020Mapping.Import);
+ writer.writeArgument(moduleName);
+ }
+
+ @Override
+ public void startRevisionDateNode(final Date date) {
+ writer.startStatement(Rfc6020Mapping.RevisionDate);
+ writer.writeArgument(SimpleDateFormatUtil.getRevisionFormat().format(date));
+ }
+
+ @Override
+ public void startUsesNode(final QName groupingName) {
+ writer.startStatement(Rfc6020Mapping.Uses);
+ writer.writeArgument(groupingName);
+ }
+
+ @Override
+ public void startAugmentNode(final SchemaPath targetPath) {
+ writer.startStatement(Rfc6020Mapping.Augment);
+ writer.writeArgument(targetPath);
+ }
+
+ @Override
+ public void startConfigNode(final boolean config) {
+ writer.startStatement(Rfc6020Mapping.Config);
+ writer.writeArgument(Boolean.toString(config));
+ }
+
+ @Override
+ public void startLengthNode(final String lengthString) {
+ writer.startStatement(Rfc6020Mapping.Length);
+ writer.writeArgument(lengthString);
+ }
+
+ @Override
+ public void startMaxElementsNode(final Integer max) {
+ writer.startStatement(Rfc6020Mapping.MaxElements);
+ writer.writeArgument(max.toString());
+ }
+
+ @Override
+ public void startMinElementsNode(final Integer min) {
+ writer.startStatement(Rfc6020Mapping.MinElements);
+ writer.writeArgument(min.toString());
+ }
+
+ @Override
+ public void startPresenceNode(final boolean presence) {
+ writer.startStatement(Rfc6020Mapping.Presence);
+ writer.writeArgument(Boolean.toString(presence));
+ }
+
+ @Override
+ public void startOrderedByNode(final String ordering) {
+ writer.startStatement(Rfc6020Mapping.OrderedBy);
+ writer.writeArgument(ordering);
+ }
+
+ @Override
+ public void startRangeNode(final String rangeString) {
+ writer.startStatement(Rfc6020Mapping.Range);
+ writer.writeArgument(rangeString);
+ }
+
+ @Override
+ public void startFractionDigitsNode(final Integer fractionDigits) {
+ writer.startStatement(Rfc6020Mapping.FractionDigits);
+ writer.writeArgument(fractionDigits.toString());
+ }
+
+ @Override
+ public void startRefineNode(final SchemaPath path) {
+ writer.startStatement(Rfc6020Mapping.Refine);
+ writer.writeArgument(path);
+ }
+
+ @Override
+ public void startMandatoryNode(final boolean mandatory) {
+ writer.startStatement(Rfc6020Mapping.Mandatory);
+ writer.writeArgument(Boolean.toString(mandatory));
+ }
+
+ @Override
+ public void startAnyxmlNode(final QName qName) {
+ writer.startStatement(Rfc6020Mapping.Anyxml);
+ writer.writeArgument(qName);
+ }
+
+ @Override
+ public void startUnknownNode(final StatementDefinition def) {
+ writer.startStatement(def);
+ }
+
+ @Override
+ public void startUnknownNode(final StatementDefinition def, final String nodeParameter) {
+ writer.startStatement(def);
+ writer.writeArgument(nodeParameter);
+ }
+
+ @Override
+ public void startYinElementNode(final boolean yinElement) {
+ writer.startStatement(Rfc6020Mapping.YinElement);
+ writer.writeArgument(Boolean.toString(yinElement));
+ }
+
+ @Override
+ public void startWhenNode(final RevisionAwareXPath revisionAwareXPath) {
+ writer.startStatement(Rfc6020Mapping.When);
+ writer.writeArgument(revisionAwareXPath);
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.export;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.BiMap;
+import com.google.common.collect.HashBiMap;
+import java.net.URI;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Map.Entry;
+import javax.annotation.Nullable;
+import javax.annotation.concurrent.NotThreadSafe;
+import javax.xml.XMLConstants;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamWriter;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.YangConstants;
+import org.opendaylight.yangtools.yang.model.api.RevisionAwareXPath;
+import org.opendaylight.yangtools.yang.model.api.Rfc6020Mapping;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
+
+@Beta
+@NotThreadSafe
+class SingleModuleYinStatementWriter implements StatementTextWriter {
+
+ private final XMLStreamWriter writer;
+ private final URI currentModuleNs;
+ private final BiMap<String, URI> prefixToNamespace;
+ private StatementDefinition currentStatement;
+
+ private SingleModuleYinStatementWriter(final XMLStreamWriter writer, final URI moduleNamespace,
+ final Map<String, URI> prefixToNs) {
+ super();
+ this.writer = writer;
+ this.currentModuleNs = moduleNamespace;
+ this.prefixToNamespace = HashBiMap.create(prefixToNs);
+ initializeYinNamespaceInXml();
+
+ }
+
+ private void initializeYinNamespaceInXml() {
+ try {
+ final String defaultNs = writer.getNamespaceContext().getNamespaceURI(XMLConstants.NULL_NS_URI);
+ if (defaultNs == null) {
+ writer.setDefaultNamespace(YangConstants.RFC6020_YIN_NAMESPACE.toString());
+ } else if (!YangConstants.RFC6020_YIN_NAMESPACE.toString().equals(defaultNs)) {
+ // FIXME: Implement support for exporting YIN as part of other XML document.
+ throw new UnsupportedOperationException("Not implemented support for nesting YIN in different XML element.");
+ }
+ } catch (final XMLStreamException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ static final StatementTextWriter create(final XMLStreamWriter writer, final URI moduleNs,
+ final Map<String, URI> prefixToNs) {
+ return new SingleModuleYinStatementWriter(writer, moduleNs, prefixToNs);
+ }
+
+ @Override
+ public void startStatement(final StatementDefinition statement) {
+ currentStatement = Preconditions.checkNotNull(statement);
+ try {
+ writeStartXmlElement(statement.getStatementName());
+ if (Rfc6020Mapping.Module.equals(statement) || Rfc6020Mapping.Submodule.equals(statement)) {
+ declareXmlNamespaces(prefixToNamespace);
+ }
+ } catch (final XMLStreamException e) {
+ // FIXME: Introduce proper expression
+ throw new IllegalStateException(e);
+ }
+ }
+
+ @Override
+ public void endStatement() {
+ currentStatement = null;
+ try {
+ writeXmlEndElement();
+ } catch (final XMLStreamException e) {
+ // FIXME: Introduce proper expression
+ throw new IllegalStateException(e);
+ }
+ }
+
+ @Override
+ public void writeArgument(final String strRep) {
+ checkArgumentApplicable();
+ writeArgument0(strRep);
+ }
+
+ @Override
+ public void writeArgument(final QName value) {
+ checkArgumentApplicable();
+ final String valueStr = toPrefixedString(value);
+ writeArgument0(valueStr);
+ }
+
+ @Override
+ public void writeArgument(final SchemaPath targetPath) {
+ checkArgumentApplicable();
+ final StringBuilder valueStr = new StringBuilder();
+ if(targetPath.isAbsolute()) {
+ valueStr.append("/");
+ }
+ final Iterator<QName> argIt = targetPath.getPathFromRoot().iterator();
+ while(argIt.hasNext()) {
+ valueStr.append(toPrefixedString(argIt.next()));
+ if(argIt.hasNext()) {
+ valueStr.append("/");
+ }
+ }
+ writeArgument0(valueStr.toString());
+ }
+
+ @Override
+ public void writeArgument(final RevisionAwareXPath xpath) {
+ checkArgumentApplicable();
+ // FIXME: This implementation assumes prefixes are unchanged
+ // and were not changed in schema context.
+ writeArgument0(xpath.toString());
+ }
+
+
+ private void writeArgument0(final String strRep) {
+ try {
+ if (isArgumentYinElement(currentStatement)) {
+ writeStartXmlElement(currentStatement.getArgumentName());
+ writeXmlText(strRep);
+ writeXmlEndElement();
+ } else {
+ writeXmlArgument(currentStatement.getArgumentName(), strRep);
+ }
+ } catch (final XMLStreamException e) {
+ // FIXME: throw proper exception
+ throw new IllegalStateException(e);
+ }
+ }
+
+ private boolean isArgumentYinElement(StatementDefinition currentStatement2) {
+ // FIXME: Implement this
+ return false;
+ }
+
+ private void checkArgumentApplicable() {
+ Preconditions.checkState(currentStatement != null, "No statement is opened.");
+ Preconditions.checkState(currentStatement.getArgumentName() != null, "Statement %s does not take argument.",
+ currentStatement.getArgumentName());
+ }
+
+
+
+ private String toPrefixedString(@Nullable final String prefix, final String localName) {
+ if (prefix == null || prefix.isEmpty()) {
+ return localName;
+ }
+ return prefix + ":" + localName;
+ }
+
+ private String toPrefixedString(final QName value) {
+ final URI valueNs = value.getNamespace();
+ final String valueLocal = value.getLocalName();
+ if (currentModuleNs.equals(valueNs)) {
+ return valueLocal;
+ }
+ final String prefix = ensureAndGetXmlNamespacePrefix(valueNs);
+ return toPrefixedString(prefix, valueLocal);
+ }
+
+ private @Nullable String ensureAndGetXmlNamespacePrefix(final URI namespace) {
+ if(YangConstants.RFC6020_YANG_NAMESPACE.equals(namespace)) {
+ // YANG namespace does not have prefix if used in arguments.
+ return null;
+
+ }
+ String prefix = writer.getNamespaceContext().getPrefix(namespace.toString());
+ if (prefix == null) {
+ // FIXME: declare prefix
+ prefix =prefixToNamespace.inverse().get(namespace);
+ }
+ if(prefix == null) {
+ throw new IllegalArgumentException("Namespace " + namespace + " is not bound to imported prefixes.");
+ }
+ return prefix;
+ }
+
+ private void writeXmlText(final String strRep) throws XMLStreamException {
+ writer.writeCharacters(strRep);
+ }
+
+ private void declareXmlNamespaces(final Map<String, URI> prefixToNamespace) {
+ try {
+ writer.writeDefaultNamespace(YangConstants.RFC6020_YIN_NAMESPACE.toString());
+ for (final Entry<String, URI> nsDeclaration : prefixToNamespace.entrySet()) {
+ writer.writeNamespace(nsDeclaration.getKey(), nsDeclaration.getValue().toString());
+ }
+ } catch (final XMLStreamException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ private void writeXmlEndElement() throws XMLStreamException {
+ writer.writeEndElement();
+ }
+
+ private void writeXmlArgument(final QName qName, final String value) throws XMLStreamException {
+ writer.writeAttribute(qName.getNamespace().toString(), qName.getLocalName(), value);
+ }
+
+ private void writeStartXmlElement(final QName name) throws XMLStreamException {
+ writer.writeStartElement(name.getNamespace().toString(), name.getLocalName());
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */package org.opendaylight.yangtools.yang.model.export;
+
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.RevisionAwareXPath;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
+
+interface StatementTextWriter {
+
+
+ void startStatement(StatementDefinition statement);
+
+ void writeArgument(RevisionAwareXPath xpath);
+
+ void writeArgument(QName name);
+
+ void writeArgument(String argStr);
+
+ void writeArgument(SchemaPath targetPath);
+
+ void endStatement();
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.export;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.BiMap;
+import com.google.common.collect.HashBiMap;
+import java.io.OutputStream;
+import java.net.URI;
+import java.util.Date;
+import java.util.Map;
+import javax.xml.stream.XMLOutputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamWriter;
+import org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.ModuleImport;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+public class YinExportUtils {
+
+
+ private YinExportUtils() {
+ throw new UnsupportedOperationException("Utility class");
+ }
+
+
+ /**
+ *
+ * Returns well-formed file name of YIN file as defined in RFC6020.
+ *
+ * @param name Module or submodule name
+ * @param revision Revision of module or submodule
+ * @return well-formed file name of YIN file as defined in RFC6020.
+ */
+ public static String wellFormedYinName(final String name, final Date revision) {
+ return wellFormedYinName(name, SimpleDateFormatUtil.getRevisionFormat().format(revision));
+ }
+
+ /**
+ *
+ * Returns well-formed file name of YIN file as defined in RFC6020.
+ *
+ * @param name
+ * name Module or submodule name
+ * @param revision
+ * Revision of module or submodule
+ * @return well-formed file name of YIN file as defined in RFC6020.
+ */
+ public static String wellFormedYinName(final String name, final String revision) {
+ return String.format("%s@%s.yin", Preconditions.checkNotNull(name),Preconditions.checkNotNull(revision));
+ }
+
+ /**
+ * Writes YIN representation of supplied module to specified output stream.
+ *
+ * @param ctx
+ * Schema Context which contains module and extension definitions
+ * to be used during export of model.
+ * @param module
+ * Module to be exported.
+ * @param str
+ * Output stream to which YIN representation of model will be
+ * written.
+ * @throws XMLStreamException
+ */
+ public static void writeModuleToOutputStream(final SchemaContext ctx, final Module module, final OutputStream str) throws XMLStreamException {
+ final XMLOutputFactory factory = XMLOutputFactory.newFactory();
+ final XMLStreamWriter xmlStreamWriter = factory.createXMLStreamWriter(str);
+ writeModuleToOutputStream(ctx,module, xmlStreamWriter);
+ }
+
+ private static void writeModuleToOutputStream(final SchemaContext ctx, final Module module, final XMLStreamWriter xmlStreamWriter) {
+ final URI moduleNs = module.getNamespace();
+ final Map<String, URI> prefixToNs = prefixToNamespace(ctx,module);
+ final StatementTextWriter yinWriter = SingleModuleYinStatementWriter.create(xmlStreamWriter, moduleNs, prefixToNs);
+ SchemaContextEmitter.writeToStatementWriter(module, ctx,yinWriter);
+ }
+
+ private static Map<String, URI> prefixToNamespace(final SchemaContext ctx, final Module module) {
+ final BiMap<String, URI> prefixMap = HashBiMap.create(module.getImports().size() + 1);
+ prefixMap.put(module.getPrefix(), module.getNamespace());
+ for(final ModuleImport imp : module.getImports()) {
+ final String prefix = imp.getPrefix();
+ final URI namespace = getModuleNamespace(ctx,imp.getModuleName());
+ prefixMap.put(prefix, namespace);
+ }
+ return prefixMap;
+ }
+
+ private static URI getModuleNamespace(final SchemaContext ctx, final String moduleName) {
+ for(final Module module : ctx.getModules()) {
+ if(moduleName.equals(module.getName())) {
+ return module.getNamespace();
+ }
+ }
+ throw new IllegalArgumentException("Module " + moduleName + "does not exists in provided schema context");
+ }
+
+}
--- /dev/null
+package org.opendaylight.yangtools.yang.model.export.test;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.OutputStream;
+import java.net.URISyntaxException;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+import org.junit.Before;
+import org.junit.Test;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.export.YinExportUtils;
+import org.opendaylight.yangtools.yang.model.repo.api.SchemaContextFactory;
+import org.opendaylight.yangtools.yang.model.repo.api.SchemaSourceFilter;
+import org.opendaylight.yangtools.yang.model.repo.api.SchemaSourceRepresentation;
+import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
+import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
+import org.opendaylight.yangtools.yang.model.repo.spi.PotentialSchemaSource;
+import org.opendaylight.yangtools.yang.model.repo.spi.SchemaListenerRegistration;
+import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceListener;
+import org.opendaylight.yangtools.yang.model.repo.util.FilesystemSchemaSourceCache;
+import org.opendaylight.yangtools.yang.parser.repo.SharedSchemaRepository;
+import org.opendaylight.yangtools.yang.parser.util.TextToASTTransformer;
+
+public class SimpleModuleTest {
+
+ private static final File TEST_MODELS_FOLDER;
+
+ static {
+ try {
+ TEST_MODELS_FOLDER = new File(SimpleModuleTest.class.getResource("/yang/").toURI());
+ } catch (final URISyntaxException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ private SharedSchemaRepository schemaRegistry;
+ private FilesystemSchemaSourceCache<YangTextSchemaSource> fileSourceProvider;
+ private SchemaContextFactory schemaContextFactory;
+ private Set<SourceIdentifier> allTestSources;
+
+ @Before
+ public void init() {
+ schemaRegistry = new SharedSchemaRepository("test");
+ fileSourceProvider = new FilesystemSchemaSourceCache<YangTextSchemaSource>(schemaRegistry,
+ YangTextSchemaSource.class, TEST_MODELS_FOLDER);
+ final TextToASTTransformer astTransformer = TextToASTTransformer.create(schemaRegistry, schemaRegistry);
+ schemaRegistry.registerSchemaSourceListener(astTransformer);
+
+ schemaContextFactory = schemaRegistry.createSchemaContextFactory(SchemaSourceFilter.ALWAYS_ACCEPT);
+ allTestSources = new HashSet<>();
+ final SchemaListenerRegistration reg = schemaRegistry.registerSchemaSourceListener(new SchemaSourceListener() {
+
+ @Override
+ public void schemaSourceUnregistered(final PotentialSchemaSource<?> source) {
+ // NOOP
+ }
+
+ @Override
+ public void schemaSourceRegistered(final Iterable<PotentialSchemaSource<?>> sources) {
+ for (final PotentialSchemaSource<?> source : sources) {
+ allTestSources.add(source.getSourceIdentifier());
+ }
+ }
+
+ @Override
+ public void schemaSourceEncountered(final SchemaSourceRepresentation source) {
+ // NOOP
+ }
+ });
+ reg.close();
+ }
+
+ @Test
+ public void testGenerateAll() throws Exception {
+ testSetOfModules(allTestSources);
+ }
+
+ private void testSetOfModules(final Collection<SourceIdentifier> source) throws Exception {
+ final SchemaContext schemaContext = schemaContextFactory.createSchemaContext(source).checkedGet();
+ final File outDir = new File("target/collection");
+ outDir.mkdirs();
+ for (final Module module : schemaContext.getModules()) {
+ exportModule(schemaContext, module, outDir);
+ }
+ }
+
+ private File exportModule(final SchemaContext schemaContext, final Module module, final File outDir)
+ throws Exception {
+ final File outFile = new File(outDir, YinExportUtils.wellFormedYinName(module.getName(), module.getRevision()));
+ try (OutputStream output = new FileOutputStream(outFile)) {
+ YinExportUtils.writeModuleToOutputStream(schemaContext, module, output);
+ }
+ return outFile;
+ }
+}
--- /dev/null
+module ietf-inet-types {
+
+ namespace "urn:ietf:params:xml:ns:yang:ietf-inet-types";
+ prefix "inet";
+
+ organization
+ "IETF NETMOD (NETCONF Data Modeling Language) Working Group";
+
+ contact
+ "WG Web: <http://tools.ietf.org/wg/netmod/>
+ WG List: <mailto:netmod@ietf.org>
+
+ WG Chair: David Partain
+ <mailto:david.partain@ericsson.com>
+
+ WG Chair: David Kessens
+ <mailto:david.kessens@nsn.com>
+
+ Editor: Juergen Schoenwaelder
+ <mailto:j.schoenwaelder@jacobs-university.de>";
+
+ description
+ "This module contains a collection of generally useful derived
+ YANG data types for Internet addresses and related things.
+
+ Copyright (c) 2010 IETF Trust and the persons identified as
+ authors of the code. All rights reserved.
+
+
+
+ Redistribution and use in source and binary forms, with or without
+ modification, is permitted pursuant to, and subject to the license
+ terms contained in, the Simplified BSD License set forth in Section
+ 4.c of the IETF Trust's Legal Provisions Relating to IETF Documents
+ (http://trustee.ietf.org/license-info).
+
+ This version of this YANG module is part of RFC 6021; see
+ the RFC itself for full legal notices.";
+
+ revision 2010-09-24 {
+ description
+ "Initial revision.";
+ reference
+ "RFC 6021: Common YANG Data Types";
+ }
+
+ /*** collection of protocol field related types ***/
+
+ typedef ip-version {
+ type enumeration {
+ enum unknown {
+ value "0";
+ description
+ "An unknown or unspecified version of the Internet protocol.";
+ }
+ enum ipv4 {
+ value "1";
+ description
+ "The IPv4 protocol as defined in RFC 791.";
+ }
+ enum ipv6 {
+ value "2";
+ description
+ "The IPv6 protocol as defined in RFC 2460.";
+ }
+ }
+ description
+ "This value represents the version of the IP protocol.
+
+ In the value set and its semantics, this type is equivalent
+ to the InetVersion textual convention of the SMIv2.";
+ reference
+ "RFC 791: Internet Protocol
+ RFC 2460: Internet Protocol, Version 6 (IPv6) Specification
+ RFC 4001: Textual Conventions for Internet Network Addresses";
+ }
+
+ typedef dscp {
+ type uint8 {
+ range "0..63";
+ }
+ description
+ "The dscp type represents a Differentiated Services Code-Point
+ that may be used for marking packets in a traffic stream.
+
+ In the value set and its semantics, this type is equivalent
+ to the Dscp textual convention of the SMIv2.";
+ reference
+ "RFC 3289: Management Information Base for the Differentiated
+ Services Architecture
+ RFC 2474: Definition of the Differentiated Services Field
+ (DS Field) in the IPv4 and IPv6 Headers
+ RFC 2780: IANA Allocation Guidelines For Values In
+ the Internet Protocol and Related Headers";
+ }
+
+ typedef ipv6-flow-label {
+ type uint32 {
+ range "0..1048575";
+ }
+ description
+ "The flow-label type represents flow identifier or Flow Label
+ in an IPv6 packet header that may be used to discriminate
+ traffic flows.
+
+ In the value set and its semantics, this type is equivalent
+ to the IPv6FlowLabel textual convention of the SMIv2.";
+ reference
+ "RFC 3595: Textual Conventions for IPv6 Flow Label
+ RFC 2460: Internet Protocol, Version 6 (IPv6) Specification";
+ }
+
+ typedef port-number {
+ type uint16 {
+ range "0..65535";
+ }
+ description
+ "The port-number type represents a 16-bit port number of an
+ Internet transport layer protocol such as UDP, TCP, DCCP, or
+ SCTP. Port numbers are assigned by IANA. A current list of
+ all assignments is available from <http://www.iana.org/>.
+
+ Note that the port number value zero is reserved by IANA. In
+ situations where the value zero does not make sense, it can
+ be excluded by subtyping the port-number type.
+
+ In the value set and its semantics, this type is equivalent
+ to the InetPortNumber textual convention of the SMIv2.";
+ reference
+ "RFC 768: User Datagram Protocol
+ RFC 793: Transmission Control Protocol
+ RFC 4960: Stream Control Transmission Protocol
+ RFC 4340: Datagram Congestion Control Protocol (DCCP)
+ RFC 4001: Textual Conventions for Internet Network Addresses";
+ }
+
+ /*** collection of autonomous system related types ***/
+
+ typedef as-number {
+ type uint32;
+ description
+ "The as-number type represents autonomous system numbers
+ which identify an Autonomous System (AS). An AS is a set
+ of routers under a single technical administration, using
+ an interior gateway protocol and common metrics to route
+ packets within the AS, and using an exterior gateway
+ protocol to route packets to other ASs'. IANA maintains
+ the AS number space and has delegated large parts to the
+ regional registries.
+
+ Autonomous system numbers were originally limited to 16
+ bits. BGP extensions have enlarged the autonomous system
+ number space to 32 bits. This type therefore uses an uint32
+ base type without a range restriction in order to support
+ a larger autonomous system number space.
+
+ In the value set and its semantics, this type is equivalent
+ to the InetAutonomousSystemNumber textual convention of
+ the SMIv2.";
+ reference
+ "RFC 1930: Guidelines for creation, selection, and registration
+ of an Autonomous System (AS)
+ RFC 4271: A Border Gateway Protocol 4 (BGP-4)
+ RFC 4893: BGP Support for Four-octet AS Number Space
+ RFC 4001: Textual Conventions for Internet Network Addresses";
+ }
+
+ /*** collection of IP address and hostname related types ***/
+
+ typedef ip-address {
+ type union {
+ type inet:ipv4-address;
+ type inet:ipv6-address;
+ }
+ description
+ "The ip-address type represents an IP address and is IP
+ version neutral. The format of the textual representations
+ implies the IP version.";
+ }
+
+ typedef ipv4-address {
+ type string {
+ pattern
+ '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}'
+ + '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])'
+ + '(%[\p{N}\p{L}]+)?';
+ }
+ description
+ "The ipv4-address type represents an IPv4 address in
+ dotted-quad notation. The IPv4 address may include a zone
+ index, separated by a % sign.
+
+ The zone index is used to disambiguate identical address
+ values. For link-local addresses, the zone index will
+ typically be the interface index number or the name of an
+ interface. If the zone index is not present, the default
+ zone of the device will be used.
+
+ The canonical format for the zone index is the numerical
+ format";
+ }
+
+ typedef ipv6-address {
+ type string {
+ pattern '((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}'
+ + '((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|'
+ + '(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.){3}'
+ + '(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))'
+ + '(%[\p{N}\p{L}]+)?';
+ pattern '(([^:]+:){6}(([^:]+:[^:]+)|(.*\..*)))|'
+ + '((([^:]+:)*[^:]+)?::(([^:]+:)*[^:]+)?)'
+ + '(%.+)?';
+ }
+ description
+ "The ipv6-address type represents an IPv6 address in full,
+ mixed, shortened, and shortened-mixed notation. The IPv6
+ address may include a zone index, separated by a % sign.
+
+
+
+
+
+ The zone index is used to disambiguate identical address
+ values. For link-local addresses, the zone index will
+ typically be the interface index number or the name of an
+ interface. If the zone index is not present, the default
+ zone of the device will be used.
+
+ The canonical format of IPv6 addresses uses the compressed
+ format described in RFC 4291, Section 2.2, item 2 with the
+ following additional rules: the :: substitution must be
+ applied to the longest sequence of all-zero 16-bit chunks
+ in an IPv6 address. If there is a tie, the first sequence
+ of all-zero 16-bit chunks is replaced by ::. Single
+ all-zero 16-bit chunks are not compressed. The canonical
+ format uses lowercase characters and leading zeros are
+ not allowed. The canonical format for the zone index is
+ the numerical format as described in RFC 4007, Section
+ 11.2.";
+ reference
+ "RFC 4291: IP Version 6 Addressing Architecture
+ RFC 4007: IPv6 Scoped Address Architecture
+ RFC 5952: A Recommendation for IPv6 Address Text Representation";
+ }
+
+ typedef ip-prefix {
+ type union {
+ type inet:ipv4-prefix;
+ type inet:ipv6-prefix;
+ }
+ description
+ "The ip-prefix type represents an IP prefix and is IP
+ version neutral. The format of the textual representations
+ implies the IP version.";
+ }
+
+ typedef ipv4-prefix {
+ type string {
+ pattern
+ '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}'
+ + '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])'
+ + '/(([0-9])|([1-2][0-9])|(3[0-2]))';
+ }
+ description
+ "The ipv4-prefix type represents an IPv4 address prefix.
+ The prefix length is given by the number following the
+ slash character and must be less than or equal to 32.
+
+
+
+ A prefix length value of n corresponds to an IP address
+ mask that has n contiguous 1-bits from the most
+ significant bit (MSB) and all other bits set to 0.
+
+ The canonical format of an IPv4 prefix has all bits of
+ the IPv4 address set to zero that are not part of the
+ IPv4 prefix.";
+ }
+
+ typedef ipv6-prefix {
+ type string {
+ pattern '((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}'
+ + '((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|'
+ + '(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.){3}'
+ + '(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))'
+ + '(/(([0-9])|([0-9]{2})|(1[0-1][0-9])|(12[0-8])))';
+ pattern '(([^:]+:){6}(([^:]+:[^:]+)|(.*\..*)))|'
+ + '((([^:]+:)*[^:]+)?::(([^:]+:)*[^:]+)?)'
+ + '(/.+)';
+ }
+ description
+ "The ipv6-prefix type represents an IPv6 address prefix.
+ The prefix length is given by the number following the
+ slash character and must be less than or equal 128.
+
+ A prefix length value of n corresponds to an IP address
+ mask that has n contiguous 1-bits from the most
+ significant bit (MSB) and all other bits set to 0.
+
+ The IPv6 address should have all bits that do not belong
+ to the prefix set to zero.
+
+ The canonical format of an IPv6 prefix has all bits of
+ the IPv6 address set to zero that are not part of the
+ IPv6 prefix. Furthermore, IPv6 address is represented
+ in the compressed format described in RFC 4291, Section
+ 2.2, item 2 with the following additional rules: the ::
+ substitution must be applied to the longest sequence of
+ all-zero 16-bit chunks in an IPv6 address. If there is
+ a tie, the first sequence of all-zero 16-bit chunks is
+ replaced by ::. Single all-zero 16-bit chunks are not
+ compressed. The canonical format uses lowercase
+ characters and leading zeros are not allowed.";
+ reference
+ "RFC 4291: IP Version 6 Addressing Architecture";
+ }
+
+
+ /*** collection of domain name and URI types ***/
+
+ typedef domain-name {
+ type string {
+ pattern '((([a-zA-Z0-9_]([a-zA-Z0-9\-_]){0,61})?[a-zA-Z0-9]\.)*'
+ + '([a-zA-Z0-9_]([a-zA-Z0-9\-_]){0,61})?[a-zA-Z0-9]\.?)'
+ + '|\.';
+ length "1..253";
+ }
+ description
+ "The domain-name type represents a DNS domain name. The
+ name SHOULD be fully qualified whenever possible.
+
+ Internet domain names are only loosely specified. Section
+ 3.5 of RFC 1034 recommends a syntax (modified in Section
+ 2.1 of RFC 1123). The pattern above is intended to allow
+ for current practice in domain name use, and some possible
+ future expansion. It is designed to hold various types of
+ domain names, including names used for A or AAAA records
+ (host names) and other records, such as SRV records. Note
+ that Internet host names have a stricter syntax (described
+ in RFC 952) than the DNS recommendations in RFCs 1034 and
+ 1123, and that systems that want to store host names in
+ schema nodes using the domain-name type are recommended to
+ adhere to this stricter standard to ensure interoperability.
+
+ The encoding of DNS names in the DNS protocol is limited
+ to 255 characters. Since the encoding consists of labels
+ prefixed by a length bytes and there is a trailing NULL
+ byte, only 253 characters can appear in the textual dotted
+ notation.
+
+ The description clause of schema nodes using the domain-name
+ type MUST describe when and how these names are resolved to
+ IP addresses. Note that the resolution of a domain-name value
+ may require to query multiple DNS records (e.g., A for IPv4
+ and AAAA for IPv6). The order of the resolution process and
+ which DNS record takes precedence can either be defined
+ explicitely or it may depend on the configuration of the
+ resolver.
+
+ Domain-name values use the US-ASCII encoding. Their canonical
+ format uses lowercase US-ASCII characters. Internationalized
+ domain names MUST be encoded in punycode as described in RFC
+ 3492";
+ reference
+ "RFC 952: DoD Internet Host Table Specification
+ RFC 1034: Domain Names - Concepts and Facilities
+ RFC 1123: Requirements for Internet Hosts -- Application
+ and Support
+ RFC 2782: A DNS RR for specifying the location of services
+ (DNS SRV)
+ RFC 3492: Punycode: A Bootstring encoding of Unicode for
+ Internationalized Domain Names in Applications
+ (IDNA)
+ RFC 5891: Internationalizing Domain Names in Applications
+ (IDNA): Protocol";
+ }
+
+ typedef host {
+ type union {
+ type inet:ip-address;
+ type inet:domain-name;
+ }
+ description
+ "The host type represents either an IP address or a DNS
+ domain name.";
+ }
+
+ typedef uri {
+ type string;
+ description
+ "The uri type represents a Uniform Resource Identifier
+ (URI) as defined by STD 66.
+
+ Objects using the uri type MUST be in US-ASCII encoding,
+ and MUST be normalized as described by RFC 3986 Sections
+ 6.2.1, 6.2.2.1, and 6.2.2.2. All unnecessary
+ percent-encoding is removed, and all case-insensitive
+ characters are set to lowercase except for hexadecimal
+ digits, which are normalized to uppercase as described in
+ Section 6.2.2.1.
+
+ The purpose of this normalization is to help provide
+ unique URIs. Note that this normalization is not
+ sufficient to provide uniqueness. Two URIs that are
+ textually distinct after this normalization may still be
+ equivalent.
+
+ Objects using the uri type may restrict the schemes that
+ they permit. For example, 'data:' and 'urn:' schemes
+ might not be appropriate.
+
+ A zero-length URI is not a valid URI. This can be used to
+ express 'URI absent' where required.
+
+ In the value set and its semantics, this type is equivalent
+ to the Uri SMIv2 textual convention defined in RFC 5017.";
+ reference
+ "RFC 3986: Uniform Resource Identifier (URI): Generic Syntax
+ RFC 3305: Report from the Joint W3C/IETF URI Planning Interest
+ Group: Uniform Resource Identifiers (URIs), URLs,
+ and Uniform Resource Names (URNs): Clarifications
+ and Recommendations
+ RFC 5017: MIB Textual Conventions for Uniform Resource
+ Identifiers (URIs)";
+ }
+
+}
<groupId>${project.groupId}</groupId>
<artifactId>yang-model-api</artifactId>
</dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-binding</artifactId>
- </dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
package org.opendaylight.yangtools.yang.model.repo.util;
import com.google.common.annotations.Beta;
-import com.google.common.base.Objects;
+import com.google.common.base.MoreObjects;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
return new YangTextSchemaSource(sourceIdentifier) {
@Override
- protected Objects.ToStringHelper addToStringAttributes(final Objects.ToStringHelper toStringHelper) {
+ protected MoreObjects.ToStringHelper addToStringAttributes(final MoreObjects.ToStringHelper toStringHelper) {
return toStringHelper;
}
--- /dev/null
+package org.opendaylight.yangtools.yang.model.util;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Supplier;
+import com.google.common.collect.SetMultimap;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
+import org.opendaylight.yangtools.yang.model.api.ConstraintDefinition;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.ExtensionDefinition;
+import org.opendaylight.yangtools.yang.model.api.GroupingDefinition;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.ModuleIdentifier;
+import org.opendaylight.yangtools.yang.model.api.NotificationDefinition;
+import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+import org.opendaylight.yangtools.yang.model.api.Status;
+import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.UsesNode;
+
+
+public abstract class AbstractSchemaContext implements SchemaContext {
+
+ protected static final Supplier<TreeSet<Module>> MODULE_SET_SUPPLIER = new Supplier<TreeSet<Module>>() {
+ @Override
+ public TreeSet<Module> get() {
+ return new TreeSet<>(REVISION_COMPARATOR);
+ }
+ };
+
+ protected static final Comparator<Module> REVISION_COMPARATOR = new Comparator<Module>() {
+ @Override
+ public int compare(final Module o1, final Module o2) {
+ if (o2.getRevision() == null) {
+ return -1;
+ }
+
+ return o2.getRevision().compareTo(o1.getRevision());
+ }
+ };
+
+ /**
+ * @return yang sources where key is ModuleIdentifier
+ */
+ protected abstract Map<ModuleIdentifier, String> getIdentifiersToSources();
+
+ /**
+ * @return Map of modules where key is namespace
+ */
+ protected abstract SetMultimap<URI, Module> getNamespaceToModules();
+
+ /**
+ * @return Map of modules where key is name of module
+ */
+ protected abstract SetMultimap<String, Module> getNameToModules();
+
+ @Override
+ public Set<DataSchemaNode> getDataDefinitions() {
+ final Set<DataSchemaNode> dataDefs = new HashSet<>();
+ for (Module m : getModules()) {
+ dataDefs.addAll(m.getChildNodes());
+ }
+ return dataDefs;
+ }
+
+ @Override
+ public Set<NotificationDefinition> getNotifications() {
+ final Set<NotificationDefinition> notifications = new HashSet<>();
+ for (Module m : getModules()) {
+ notifications.addAll(m.getNotifications());
+ }
+ return notifications;
+ }
+
+ @Override
+ public Set<RpcDefinition> getOperations() {
+ final Set<RpcDefinition> rpcs = new HashSet<>();
+ for (Module m : getModules()) {
+ rpcs.addAll(m.getRpcs());
+ }
+ return rpcs;
+ }
+
+ @Override
+ public Set<ExtensionDefinition> getExtensions() {
+ final Set<ExtensionDefinition> extensions = new HashSet<>();
+ for (Module m : getModules()) {
+ extensions.addAll(m.getExtensionSchemaNodes());
+ }
+ return extensions;
+ }
+
+ @Override
+ public Module findModuleByName(final String name, final Date revision) {
+ for (final Module module : getNameToModules().get(name)) {
+ if (revision == null || revision.equals(module.getRevision())) {
+ return module;
+ }
+ }
+
+ return null;
+ }
+
+ @Override
+ public Set<Module> findModuleByNamespace(final URI namespace) {
+ final Set<Module> ret = getNamespaceToModules().get(namespace);
+ return ret == null ? Collections.<Module>emptySet() : ret;
+ }
+
+ @Override
+ public Module findModuleByNamespaceAndRevision(final URI namespace, final Date revision) {
+ if (namespace == null) {
+ return null;
+ }
+ for (Module module : findModuleByNamespace(namespace)) {
+ if (revision == null || revision.equals(module.getRevision())) {
+ return module;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public boolean isAugmenting() {
+ return false;
+ }
+
+ @Override
+ public boolean isAddedByUses() {
+ return false;
+ }
+
+ @Override
+ public boolean isConfiguration() {
+ return false;
+ }
+
+ @Override
+ public ConstraintDefinition getConstraints() {
+ return null;
+ }
+
+ @Override
+ public QName getQName() {
+ return SchemaContext.NAME;
+ }
+
+ @Override
+ public SchemaPath getPath() {
+ return SchemaPath.ROOT;
+ }
+
+ @Override
+ public String getDescription() {
+ return null;
+ }
+
+ @Override
+ public String getReference() {
+ return null;
+ }
+
+ @Override
+ public Status getStatus() {
+ return Status.CURRENT;
+ }
+
+ @Override
+ public List<UnknownSchemaNode> getUnknownSchemaNodes() {
+ final List<UnknownSchemaNode> result = new ArrayList<>();
+ for (Module module : getModules()) {
+ result.addAll(module.getUnknownSchemaNodes());
+ }
+ return Collections.unmodifiableList(result);
+ }
+
+ @Override
+ public Set<TypeDefinition<?>> getTypeDefinitions() {
+ final Set<TypeDefinition<?>> result = new LinkedHashSet<>();
+ for (Module module : getModules()) {
+ result.addAll(module.getTypeDefinitions());
+ }
+ return Collections.unmodifiableSet(result);
+ }
+
+ @Override
+ public Set<DataSchemaNode> getChildNodes() {
+ final Set<DataSchemaNode> result = new LinkedHashSet<>();
+ for (Module module : getModules()) {
+ result.addAll(module.getChildNodes());
+ }
+ return Collections.unmodifiableSet(result);
+ }
+
+ @Override
+ public Set<GroupingDefinition> getGroupings() {
+ final Set<GroupingDefinition> result = new LinkedHashSet<>();
+ for (Module module : getModules()) {
+ result.addAll(module.getGroupings());
+ }
+ return Collections.unmodifiableSet(result);
+ }
+
+ @Override
+ public DataSchemaNode getDataChildByName(final QName name) {
+ for (Module module : getModules()) {
+ final DataSchemaNode result = module.getDataChildByName(name);
+ if (result != null) {
+ return result;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public DataSchemaNode getDataChildByName(final String name) {
+ for (Module module : getModules()) {
+ final DataSchemaNode result = module.getDataChildByName(name);
+ if (result != null) {
+ return result;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public Set<UsesNode> getUses() {
+ return Collections.emptySet();
+ }
+
+ @Override
+ public boolean isPresenceContainer() {
+ return false;
+ }
+
+ @Override
+ public Set<AugmentationSchema> getAvailableAugmentations() {
+ return Collections.emptySet();
+ }
+
+ //FIXME: should work for submodules too
+ @Override
+ public Set<ModuleIdentifier> getAllModuleIdentifiers() {
+ return getIdentifiersToSources().keySet();
+ }
+
+ @Override
+ public Optional<String> getModuleSource(final ModuleIdentifier moduleIdentifier) {
+ String maybeSource = getIdentifiersToSources().get(moduleIdentifier);
+ return Optional.fromNullable(maybeSource);
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.html
+ */
+
+package org.opendaylight.yangtools.yang.model.util;
+
+import com.google.common.base.Function;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Predicate;
+import com.google.common.base.Strings;
+import com.google.common.collect.Collections2;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet.Builder;
+import com.google.common.collect.ImmutableSetMultimap;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Multimap;
+import com.google.common.collect.Multimaps;
+import com.google.common.collect.SetMultimap;
+import com.google.common.collect.TreeMultimap;
+import java.net.URI;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+import javax.annotation.Nullable;
+import javax.annotation.concurrent.Immutable;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.ModuleIdentifier;
+import org.opendaylight.yangtools.yang.model.api.ModuleImport;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+@Immutable
+public final class FilteringSchemaContextProxy extends AbstractSchemaContext {
+
+ //collection to be filled with filtered modules
+ private final Set<Module> filteredModules;
+
+ //collections to be filled in with filtered data
+ private final Map<ModuleIdentifier, String> identifiersToSources;
+ private final SetMultimap<URI, Module> namespaceToModules;
+ private final SetMultimap<String, Module> nameToModules;
+
+ /**
+ * Filters SchemaContext for yang modules
+ *
+ * @param delegate original SchemaContext
+ * @param rootModules modules (yang schemas) to be available and all their dependencies (modules importing rootModule and whole chain of their imports)
+ * @param additionalModuleIds (additional) modules (yang schemas) to be available and whole chain of their imports
+ *
+ */
+ public FilteringSchemaContextProxy(final SchemaContext delegate, final Collection<ModuleId> rootModules, final Set<ModuleId> additionalModuleIds) {
+
+ Preconditions.checkArgument(rootModules!=null,"Base modules cannot be null.");
+ Preconditions.checkArgument(additionalModuleIds!=null,"Additional modules cannot be null.");
+
+ final Builder<Module> filteredModulesBuilder = new Builder<>();
+
+ final SetMultimap<URI, Module> nsMap = Multimaps.newSetMultimap(new TreeMap<URI, Collection<Module>>(), MODULE_SET_SUPPLIER);
+ final SetMultimap<String, Module> nameMap = Multimaps.newSetMultimap(new TreeMap<String, Collection<Module>>(), MODULE_SET_SUPPLIER);
+
+ ImmutableMap.Builder<ModuleIdentifier, String> identifiersToSourcesBuilder = ImmutableMap.builder();
+
+ //preparing map to get all modules with one name but difference in revision
+ final TreeMultimap<String, Module> nameToModulesAll = getStringModuleTreeMultimap();
+
+ nameToModulesAll.putAll(getStringModuleMap(delegate));
+
+ //in case there is a particular dependancy to view filteredModules/yang models
+ //dependancy is checked for module name and imports
+ processForRootModules(delegate, rootModules, filteredModulesBuilder);
+
+ //adding additional modules
+ processForAdditionalModules(delegate, additionalModuleIds, filteredModulesBuilder);
+
+ filteredModulesBuilder.addAll(getImportedModules(
+ Maps.uniqueIndex(delegate.getModules(), ModuleId.MODULE_TO_MODULE_ID), filteredModulesBuilder.build(), nameToModulesAll));
+
+ /**
+ * Instead of doing this on each invocation of getModules(), pre-compute
+ * it once and keep it around -- better than the set we got in.
+ */
+ this.filteredModules = filteredModulesBuilder.build();
+
+ for (final Module module :filteredModules) {
+ nameMap.put(module.getName(), module);
+ nsMap.put(module.getNamespace(), module);
+ identifiersToSourcesBuilder.put(module, module.getSource());
+ }
+
+ namespaceToModules = ImmutableSetMultimap.copyOf(nsMap);
+ nameToModules = ImmutableSetMultimap.copyOf(nameMap);
+ identifiersToSources = identifiersToSourcesBuilder.build();
+ }
+
+ private static TreeMultimap<String, Module> getStringModuleTreeMultimap() {
+ return TreeMultimap.create(new Comparator<String>() {
+ @Override
+ public int compare(String o1, String o2) {
+ return o1.compareTo(o2);
+ }
+ }, REVISION_COMPARATOR);
+ }
+
+ private void processForAdditionalModules(SchemaContext delegate, final Set<ModuleId> additionalModuleIds, Builder<Module> filteredModulesBuilder) {
+ filteredModulesBuilder.addAll(Collections2.filter(delegate.getModules(), new Predicate<Module>() {
+ @Override
+ public boolean apply(@Nullable Module module) {
+ return selectAdditionalModules(module, additionalModuleIds);
+ }
+ }));
+ }
+
+ private void processForRootModules(SchemaContext delegate, final Collection<ModuleId> rootModules, Builder<Module> filteredModulesBuilder) {
+ filteredModulesBuilder.addAll(Collections2.filter(delegate.getModules(), new Predicate<Module>() {
+ @Override
+ public boolean apply(@Nullable Module module) {
+ return checkModuleDependency(module, rootModules);
+ }
+ }));
+ }
+
+ private Multimap<String, Module> getStringModuleMap(SchemaContext delegate) {
+ return Multimaps.index(delegate.getModules(), new Function<Module, String>() {
+ @Override
+ public String apply(Module input) {
+ return input.getName();
+ }
+ });
+ }
+
+ //dealing with imported module other than root and directly importing root
+ private static Collection<Module> getImportedModules(Map<ModuleId, Module> allModules, Set<Module> baseModules, TreeMultimap<String, Module> nameToModulesAll) {
+
+ List<Module> relatedModules = Lists.newLinkedList();
+
+ for (Module module : baseModules) {
+ for (ModuleImport moduleImport : module.getImports()) {
+
+ Date revisionDate = moduleImport.getRevision() == null ?
+ nameToModulesAll.get(moduleImport.getModuleName()).first().getRevision() : moduleImport.getRevision();
+
+ ModuleId key = new ModuleId(moduleImport.getModuleName(),revisionDate);
+ Module importedModule = allModules.get(key);
+
+ Preconditions.checkArgument(importedModule != null, "Invalid schema, cannot find imported module: %s from module: %s, %s, modules:%s", key, module.getQNameModule(), module.getName() );
+ relatedModules.add(importedModule);
+
+ //calling imports recursive
+ relatedModules.addAll(getImportedModules(allModules, Collections.singleton(importedModule), nameToModulesAll));
+
+ }
+ }
+
+ return relatedModules;
+ }
+
+ @Override
+ protected Map<ModuleIdentifier, String> getIdentifiersToSources() {
+ return identifiersToSources;
+ }
+
+ public Set<Module> getModules() {
+ return filteredModules;
+ }
+
+ @Override
+ protected SetMultimap<URI, Module> getNamespaceToModules() {
+ return namespaceToModules;
+ }
+
+ @Override
+ protected SetMultimap<String, Module> getNameToModules() {
+ return nameToModules;
+ }
+
+ private boolean selectAdditionalModules(Module module, Set<ModuleId> additionalModules){
+
+ if(additionalModules.contains(new ModuleId(module.getName(), module.getRevision()))){
+
+ return true;
+ }
+
+ return false;
+ };
+
+ //check for any dependency regarding given string
+ private boolean checkModuleDependency(Module module, Collection<ModuleId> rootModules) {
+
+ for (ModuleId rootModule : rootModules) {
+
+ if(rootModule.equals(new ModuleId(module.getName(), module.getRevision()))) {
+ return true;
+ }
+
+ //handling/checking imports regarding root modules
+ for (ModuleImport moduleImport : module.getImports()) {
+
+ if(moduleImport.getModuleName().equals(rootModule.getName())) {
+
+ if(moduleImport.getRevision() != null && !moduleImport.getRevision().equals(rootModule.getRev())) {
+ return false;
+ }
+
+ return true;
+ }
+ }
+
+ //submodules handling
+ for (Module moduleSub : module.getSubmodules()) {
+ return checkModuleDependency(moduleSub, rootModules);
+ }
+ }
+
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return String.format("SchemaContextProxyImpl{filteredModules=%s}", filteredModules);
+ }
+
+ public static final class ModuleId {
+ private final String name;
+ private final Date rev;
+
+ public ModuleId(String name, Date rev) {
+ Preconditions.checkArgument(!Strings.isNullOrEmpty(name), "No module dependency name given. Nothing to do.");
+ this.name = name;
+ this.rev = Preconditions.checkNotNull(rev, "No revision date given. Nothing to do.");
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public Date getRev() {
+ return rev;
+ }
+
+ public static final Function<Module, ModuleId> MODULE_TO_MODULE_ID = new Function<Module, ModuleId>() {
+ @Override
+ public ModuleId apply(Module input) {
+ return new ModuleId(input.getName(), input.getRevision());
+ }
+ };
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ ModuleId moduleId = (ModuleId) o;
+
+ if (name != null ? !name.equals(moduleId.name) : moduleId.name != null) return false;
+ if (rev != null ? !rev.equals(moduleId.rev) : moduleId.rev != null) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = name != null ? name.hashCode() : 0;
+ result = 31 * result + (rev != null ? rev.hashCode() : 0);
+ return result;
+ }
+
+ @Override
+ public String toString() {
+
+ return String.format("ModuleId{name='%s', rev=%s}",name,rev);
+ }
+ }
+}
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
-
import com.google.common.base.Charsets;
import com.google.common.base.Function;
-import com.google.common.base.Objects;
+import com.google.common.base.MoreObjects;
import com.google.common.base.Optional;
import com.google.common.collect.Collections2;
import com.google.common.io.Files;
}
@Override
- protected Objects.ToStringHelper addToStringAttributes(final Objects.ToStringHelper toStringHelper) {
+ protected MoreObjects.ToStringHelper addToStringAttributes(final MoreObjects.ToStringHelper toStringHelper) {
return toStringHelper;
}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html.html
+ */
+
+package org.opendaylight.yangtools.yang.model.util;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+
+import com.google.common.collect.Sets;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.text.ParseException;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Set;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.opendaylight.yangtools.yang.common.QNameModule;
+import org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.ModuleImport;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.util.FilteringSchemaContextProxy.ModuleId;
+
+public class SchemaContextProxyTest {
+
+ private static URI namespace;
+ private static Date revision;
+ private static Date revision2;
+
+ private static final String CONFIG_NAME = "config";
+ private static final String ROOT_NAME = "root";
+ private static final String MODULE2_NAME = "module2";
+ private static final String MODULE3_NAME = "module3";
+ private static final String MODULE4_NAME = "module4";
+ private static final String MODULE41_NAME = "module41";
+ private static final String MODULE5_NAME = "module5";
+ private static final String TEST_SOURCE = "test source";
+
+ @BeforeClass
+ public static void setUp() throws ParseException, URISyntaxException {
+
+ namespace = new URI("urn:opendaylight:params:xml:ns:yang:controller:config");
+
+ revision = SimpleDateFormatUtil.getRevisionFormat().parse("2015-01-01");
+ revision2 = SimpleDateFormatUtil.getRevisionFormat().parse("2015-01-15");
+ }
+
+ private SchemaContext mockSchema(Module... module) {
+
+ SchemaContext mock = mock(SchemaContext.class);
+ doReturn(Sets.newHashSet(module)).when(mock).getModules();
+ return mock;
+ }
+
+ /**
+ * <pre>
+ * CFG(R)
+ * | \
+ * | \
+ * M2 <- M3
+ * </pre>
+ */
+ @Test
+ public void testBasic() {
+ Module moduleConfig = mockModule(CONFIG_NAME);
+ Module module2 = mockModule(MODULE2_NAME);
+ Module module3 = mockModule(MODULE3_NAME);
+
+ mockModuleImport(module2, moduleConfig);
+ mockModuleImport(module3, module2, moduleConfig);
+
+ SchemaContext schemaContext = mockSchema(moduleConfig, module2, module3);
+
+ FilteringSchemaContextProxy filteringSchemaContextProxy = createProxySchemaCtx(schemaContext, null, moduleConfig);
+ assertProxyContext(filteringSchemaContextProxy, moduleConfig, module2, module3);
+ }
+
+ /**
+ * <pre>
+ * No root or additional modules
+ * | \
+ * | \
+ * M2 <- M3
+ * </pre>
+ */
+ @Test
+ public void testNull() {
+ Module moduleConfig = mockModule(CONFIG_NAME);
+ Module module2 = mockModule(MODULE2_NAME);
+ Module module3 = mockModule(MODULE3_NAME);
+
+ mockModuleImport(module2, moduleConfig);
+ mockModuleImport(module3, module2, moduleConfig);
+
+ SchemaContext schemaContext = mockSchema(moduleConfig, module2, module3);
+
+ FilteringSchemaContextProxy filteringSchemaContextProxy = createProxySchemaCtx(schemaContext, null, null);
+ assertProxyContext(filteringSchemaContextProxy, null);
+ }
+
+ /**
+ * <pre>
+ * Config
+ * | \ (NR)
+ * | \
+ * M2 <- M3
+ * </pre>
+ */
+ @Test
+ public void testConfigDifferentRevisions() {
+ Module moduleConfigNullRevision = mockModule(CONFIG_NAME, null);
+ Module moduleConfig = mockModule(CONFIG_NAME, revision);
+ Module moduleConfig2 = mockModule(CONFIG_NAME, revision2);
+ Module module2 = mockModule(MODULE2_NAME);
+ Module module3 = mockModule(MODULE3_NAME);
+
+ mockModuleImport(module2, moduleConfig);
+ mockModuleImport(module3, module2, moduleConfigNullRevision);
+
+ SchemaContext schemaContext = mockSchema(moduleConfig, moduleConfig2, module2, module3);
+
+ FilteringSchemaContextProxy filteringSchemaContextProxy = createProxySchemaCtx(schemaContext, null, moduleConfig);
+ assertProxyContext(filteringSchemaContextProxy, moduleConfig, moduleConfig2, module2, module3);
+ }
+
+ /**
+ * <pre>
+ * CFG(R)
+ * | \
+ * | \
+ * M2<-(NullRev)M3
+ * </pre>
+ */
+ @Test
+ public void testBasicNullRevision() throws Exception {
+ Module moduleConfig = mockModule(CONFIG_NAME,SimpleDateFormatUtil.getRevisionFormat().parse("2013-04-05"));
+ Module module2 = mockModule(MODULE2_NAME, SimpleDateFormatUtil.getRevisionFormat().parse("2014-06-17"));
+ Module module20 = mockModule(MODULE2_NAME, null);
+ Module module3 = mockModule(MODULE3_NAME, SimpleDateFormatUtil.getRevisionFormat().parse("2014-06-12"));
+ Module module30 = mockModule(MODULE3_NAME, null);
+
+ mockModuleImport(module20, moduleConfig);
+ mockModuleImport(module2, moduleConfig);
+ mockModuleImport(module3, module20, moduleConfig);
+ mockModuleImport(module30, module20, moduleConfig);
+
+ SchemaContext schemaContext = mockSchema(moduleConfig, module2, module3);
+
+ FilteringSchemaContextProxy filteringSchemaContextProxy = createProxySchemaCtx(schemaContext, null, moduleConfig);
+
+ assertProxyContext(filteringSchemaContextProxy, moduleConfig, module2, module3);
+ }
+
+ /**
+ * <pre>
+ * CFG(R) ROOT(R)
+ * | \
+ * | \
+ * M2 M3
+ * </pre>
+ */
+ @Test
+ public void testBasicMoreRootModules() {
+ Module moduleConfig = mockModule(CONFIG_NAME);
+ Module moduleRoot = mockModule(ROOT_NAME);
+ Module module2 = mockModule(MODULE2_NAME);
+ Module module3 = mockModule(MODULE3_NAME);
+
+ mockModuleImport(module2, moduleConfig);
+ mockModuleImport(module3, moduleRoot);
+
+ SchemaContext schemaContext = mockSchema(moduleConfig, moduleRoot, module2, module3);
+
+ FilteringSchemaContextProxy filteringSchemaContextProxy = createProxySchemaCtx(schemaContext, null, moduleRoot, moduleConfig);
+ assertProxyContext(filteringSchemaContextProxy, moduleRoot, module3, moduleConfig, module2);
+ }
+
+ /**
+ * <pre>
+ * CFG(R)
+ * |
+ * |
+ * M2 <- M3
+ * </pre>
+ */
+ @Test
+ public void testChainNotDepend() {
+ Module moduleConfig = mockModule(CONFIG_NAME);
+ Module module2 = mockModule(MODULE2_NAME);
+ Module module3 = mockModule(MODULE3_NAME);
+
+ mockModuleImport(module2, moduleConfig);
+ mockModuleImport(module3, module2);
+
+ SchemaContext schemaContext = mockSchema(moduleConfig, module2, module3);
+
+ FilteringSchemaContextProxy filteringSchemaContextProxy = createProxySchemaCtx(schemaContext, null, moduleConfig);
+ assertProxyContext(filteringSchemaContextProxy, moduleConfig, module2);
+ }
+
+ /**
+ * <pre>
+ * CFG(R)
+ * |
+ * |
+ * M2 -> M3 -> M4 -> M5
+ * </pre>
+ */
+ @Test
+ public void testChainDependMulti() {
+ Module moduleConfig = mockModule(CONFIG_NAME);
+ Module module2 = mockModule(MODULE2_NAME);
+ Module module3 = mockModule(MODULE3_NAME);
+ Module module4 = mockModule(MODULE4_NAME);
+ Module module5 = mockModule(MODULE5_NAME);
+
+ mockModuleImport(module2, moduleConfig, module3);
+ mockModuleImport(module3, module4);
+ mockModuleImport(module4, module5);
+
+ SchemaContext schemaContext = mockSchema(moduleConfig, module2, module3, module4, module5);
+
+ FilteringSchemaContextProxy filteringSchemaContextProxy = createProxySchemaCtx(schemaContext, null, moduleConfig);
+ assertProxyContext(filteringSchemaContextProxy, moduleConfig, module2, module3, module4, module5);
+ }
+
+ /**
+ * <pre>
+ * CFG(R)
+ * |
+ * |
+ * M2 -> M3 <- M4
+ * </pre>
+ */
+ @Test
+ public void testChainNotDependMulti() {
+ Module moduleConfig = mockModule(CONFIG_NAME);
+ Module module2 = mockModule(MODULE2_NAME);
+ Module module3 = mockModule(MODULE3_NAME);
+ Module module4 = mockModule(MODULE4_NAME);
+
+ mockModuleImport(module2, moduleConfig, module3);
+ mockModuleImport(module4, module3);
+
+ SchemaContext schemaContext = mockSchema(moduleConfig, module2, module3, module4);
+
+ FilteringSchemaContextProxy filteringSchemaContextProxy = createProxySchemaCtx(schemaContext, null, moduleConfig);
+ assertProxyContext(filteringSchemaContextProxy, moduleConfig, module2, module3);
+ }
+
+ /**
+ * <pre>
+ * CFG(R)
+ * | \ \ \
+ * | \ \ \
+ * M2 M3 M4 M5
+ * </pre>
+ */
+ @Test
+ public void testChainNotMulti() {
+ Module moduleConfig = mockModule(CONFIG_NAME);
+ Module module2 = mockModule(MODULE2_NAME);
+ Module module3 = mockModule(MODULE3_NAME);
+ Module module4 = mockModule(MODULE4_NAME);
+ Module module5 = mockModule(MODULE5_NAME);
+
+ mockModuleImport(module2, moduleConfig);
+ mockModuleImport(module3, moduleConfig);
+ mockModuleImport(module4, moduleConfig);
+ mockModuleImport(module5, moduleConfig);
+
+ SchemaContext schemaContext = mockSchema(moduleConfig, module2, module3, module4, module5);
+
+ FilteringSchemaContextProxy filteringSchemaContextProxy = createProxySchemaCtx(schemaContext, null, moduleConfig);
+ assertProxyContext(filteringSchemaContextProxy, moduleConfig, module2, module3, module4, module5);
+ }
+
+ /**
+ * <pre>
+ * CFG(R)
+ * | \
+ * | \
+ * M2 <- M3 M4=M3(Different revision)
+ * </pre>
+ */
+ @Test
+ public void testBasicRevisionChange() throws Exception {
+ Module moduleConfig = mockModule(CONFIG_NAME);
+ Module module2 = mockModule(MODULE2_NAME);
+ Module module3 = mockModule(MODULE3_NAME);
+
+ Date dat = SimpleDateFormatUtil.getRevisionFormat().parse("2015-10-10");
+ Module module4 = mockModule(MODULE3_NAME, dat);
+
+ mockModuleImport(module2, moduleConfig);
+ mockModuleImport(module3, module2, moduleConfig);
+
+ SchemaContext schemaContext = mockSchema(moduleConfig, module2, module3, module4);
+
+ FilteringSchemaContextProxy filteringSchemaContextProxy = createProxySchemaCtx(schemaContext, null, moduleConfig);
+ assertProxyContext(filteringSchemaContextProxy, moduleConfig, module2, module3);
+ }
+
+ /**
+ * <pre>
+ * CFG(R)
+ * |
+ * M2 -(no revision)-> M3(R2) ... M3(R1)
+ * </pre>
+ */
+ @Test
+ public void testImportNoRevision() throws Exception {
+ Module moduleConfig = mockModule(CONFIG_NAME, revision);
+ Module module2 = mockModule(MODULE2_NAME, revision);
+
+ Module module3 = mockModule(MODULE3_NAME, null);
+ Module module30 = mockModule(MODULE3_NAME, revision);
+ Module module31 = mockModule(MODULE3_NAME, revision2);
+ mockModuleImport(module2, moduleConfig, module3);
+
+ SchemaContext schemaContext = mockSchema(moduleConfig, module2, module30, module31);
+
+ FilteringSchemaContextProxy filteringSchemaContextProxy = createProxySchemaCtx(schemaContext, null, moduleConfig);
+
+ assertProxyContext(filteringSchemaContextProxy, moduleConfig, module2, module31);
+ }
+
+ /**
+ * <pre>
+ * CFG(R)
+ * | \
+ * | \
+ * | M2 -> M3
+ * |
+ * M41(S) => M4
+ * </pre>
+ */
+ @Test
+ public void testBasicSubmodule() throws Exception {
+ Module moduleConfig = mockModule(CONFIG_NAME);
+ Module module2 = mockModule(MODULE2_NAME);
+ Module module3 = mockModule(MODULE3_NAME);
+ Module module4 = mockModule(MODULE4_NAME);
+ Module module41 = mockModule(MODULE41_NAME);
+
+ mockSubmodules(module4, module41);
+ mockModuleImport(module2, moduleConfig, module3);
+ mockModuleImport(module41, moduleConfig);
+
+ SchemaContext schemaContext = mockSchema(moduleConfig, module2, module3, module4);
+
+ FilteringSchemaContextProxy filteringSchemaContextProxy = createProxySchemaCtx(schemaContext, null, moduleConfig);
+ assertProxyContext(filteringSchemaContextProxy, moduleConfig, module2, module3, module4);
+ }
+
+ /**
+ * <pre>
+ *
+ * M2 -> M3 -> M4 -> M5
+ *
+ * </pre>
+ */
+ @Test
+ public void testChainAdditionalModules() {
+ Module module2 = mockModule(MODULE2_NAME);
+ Module module3 = mockModule(MODULE3_NAME);
+ Module module4 = mockModule(MODULE4_NAME);
+ Module module5 = mockModule(MODULE5_NAME);
+
+ mockModuleImport(module2, module3);
+ mockModuleImport(module3, module4);
+ mockModuleImport(module4, module5);
+
+ SchemaContext schemaContext = mockSchema(module2, module3, module4, module5);
+
+ FilteringSchemaContextProxy filteringSchemaContextProxy = createProxySchemaCtx(schemaContext, Sets.newHashSet(module2), null);
+ assertProxyContext(filteringSchemaContextProxy, module2, module3, module4, module5);
+ }
+
+ /**
+ * <pre>
+ *
+ * CFG(R)
+ * |
+ * | M5
+ * M2
+ *
+ * M3 -> M4
+ *
+ * </pre>
+ */
+ @Test
+ public void testChainAdditionalModulesConfig() {
+ Module moduleConfig = mockModule(CONFIG_NAME);
+ Module module2 = mockModule(MODULE2_NAME);
+
+ Module module3 = mockModule(MODULE3_NAME);
+ Module module4 = mockModule(MODULE4_NAME);
+ Module module5 = mockModule(MODULE5_NAME);
+
+ mockModuleImport(module2, moduleConfig);
+ mockModuleImport(module3, module4);
+
+ SchemaContext schemaContext = mockSchema(moduleConfig, module2, module3, module4, module5);
+
+ FilteringSchemaContextProxy filteringSchemaContextProxy = createProxySchemaCtx(schemaContext, Sets.newHashSet(module3), moduleConfig);
+ assertProxyContext(filteringSchemaContextProxy, moduleConfig, module2, module3, module4);
+ }
+
+ private void assertProxyContext(FilteringSchemaContextProxy filteringSchemaContextProxy, Module... expected) {
+
+ Set<Module> modSet = Sets.newHashSet();
+
+ if(expected!=null) {
+
+ modSet = Sets.newHashSet(expected);
+ }
+
+ Set<Module> modSetFiltering = filteringSchemaContextProxy.getModules();
+
+ assertEquals(modSet, modSetFiltering);
+
+ //asserting collections
+ if(expected!=null) {
+ for (final Module module : expected) {
+ assertEquals(module, filteringSchemaContextProxy.findModuleByName(module.getName(), module.getRevision()));
+
+ Set<Module> mod = filteringSchemaContextProxy.findModuleByNamespace(module.getNamespace());
+ assertTrue(mod.contains(module));
+
+ assertEquals(module, filteringSchemaContextProxy.findModuleByNamespaceAndRevision(module.getNamespace(), module.getRevision()));
+
+ assertEquals(module.getSource(), filteringSchemaContextProxy.getModuleSource(module).get());
+ }
+ }
+ }
+
+ private FilteringSchemaContextProxy createProxySchemaCtx(SchemaContext schemaContext, Set<Module> additionalModules, Module... modules) {
+
+ Set<Module> modulesSet = new HashSet();
+
+ if(modules!=null) {
+
+ modulesSet = Sets.newHashSet(modules);
+
+ }
+
+ return new FilteringSchemaContextProxy(schemaContext, createModuleIds(modulesSet) , createModuleIds(additionalModules));
+ }
+
+ private Set<ModuleId> createModuleIds(Set<Module> modules) {
+
+ Set<ModuleId> moduleIds = Sets.newHashSet();
+
+ if(modules!=null && modules.size()>0) {
+
+ for (Module module : modules) {
+
+ moduleIds.add(new ModuleId(module.getName(), module.getRevision()));
+ }
+ }
+
+ return moduleIds;
+ }
+
+ private void mockSubmodules(Module mainModule, Module... submodules){
+
+ Set<Module> submodulesSet = new HashSet<>();
+ submodulesSet.addAll(Arrays.asList(submodules));
+
+ doReturn(submodulesSet).when(mainModule).getSubmodules();
+ }
+
+ private void mockModuleImport(Module importer, Module... imports) {
+ Set<ModuleImport> mockedImports = Sets.newHashSet();
+ for (final Module module : imports) {
+ mockedImports.add(new ModuleImport() {
+ @Override
+ public String getModuleName() {
+ return module.getName();
+ }
+
+ @Override
+ public Date getRevision() {
+ return module.getRevision();
+ }
+
+ @Override
+ public String getPrefix() {
+ return module.getName();
+ }
+
+ @Override
+ public String toString() {
+
+ return String.format("Module: %s, revision:%s", module.getName(), module.getRevision());
+ }
+ });
+ }
+ doReturn(mockedImports).when(importer).getImports();
+ }
+
+ //mock module with revision
+ private Module mockModule(String name, final Date rev){
+
+ final Module mod = mockModule(name);
+
+ doReturn(QNameModule.create(mod.getNamespace(), rev)).when(mod).getQNameModule();
+ doReturn(rev).when(mod).getRevision();
+ doReturn(mod.getQNameModule().toString()).when(mod).toString();
+
+ return mod;
+ }
+
+ //mock module with default revision
+ private Module mockModule(String mName) {
+
+ Module mockedModule = mock(Module.class);
+ doReturn(mName).when(mockedModule).getName();
+ doReturn(revision).when(mockedModule).getRevision();
+ final URI newNamespace = URI.create(namespace.toString() + ":" + mName);
+ doReturn(newNamespace).when(mockedModule).getNamespace();
+ doReturn(QNameModule.create(newNamespace, revision)).when(mockedModule).getQNameModule();
+ doReturn(TEST_SOURCE).when(mockedModule).getSource();
+ doReturn(Sets.newHashSet()).when(mockedModule).getSubmodules();
+ doReturn(mockedModule.getQNameModule().toString()).when(mockedModule).toString();
+ mockModuleImport(mockedModule);
+
+ return mockedModule;
+ }
+}
}
if (old.getType() == null) {
- copy.setTypedef(copy(old.getTypedef(), copy, updateQName));
+ copy.setTypedef(old.getTypedef());
} else {
copy.setType(old.getType());
}
}
if (old.getType() == null) {
- copy.setTypedef(copy(old.getTypedef(), copy, updateQName));
+ copy.setTypedef(old.getTypedef());
} else {
copy.setType(old.getType());
}
*/
package org.opendaylight.yangtools.yang.parser.impl;
-import com.google.common.base.Optional;
-import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSetMultimap;
import com.google.common.collect.Multimaps;
import com.google.common.collect.SetMultimap;
import java.net.URI;
-import java.util.ArrayList;
import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.Date;
-import java.util.HashSet;
-import java.util.LinkedHashSet;
-import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
-import java.util.TreeSet;
import javax.annotation.concurrent.Immutable;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
-import org.opendaylight.yangtools.yang.model.api.ConstraintDefinition;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.ExtensionDefinition;
-import org.opendaylight.yangtools.yang.model.api.GroupingDefinition;
import org.opendaylight.yangtools.yang.model.api.Module;
import org.opendaylight.yangtools.yang.model.api.ModuleIdentifier;
-import org.opendaylight.yangtools.yang.model.api.NotificationDefinition;
-import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.opendaylight.yangtools.yang.model.api.SchemaPath;
-import org.opendaylight.yangtools.yang.model.api.Status;
-import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
-import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.UsesNode;
+import org.opendaylight.yangtools.yang.model.util.AbstractSchemaContext;
import org.opendaylight.yangtools.yang.parser.util.ModuleDependencySort;
@Immutable
-final class SchemaContextImpl implements SchemaContext {
- private static final Comparator<Module> REVISION_COMPARATOR = new Comparator<Module>() {
- @Override
- public int compare(final Module o1, final Module o2) {
- if (o2.getRevision() == null) {
- return -1;
- }
+final class SchemaContextImpl extends AbstractSchemaContext {
- return o2.getRevision().compareTo(o1.getRevision());
- }
- };
-
- private static final Supplier<TreeSet<Module>> MODULE_SET_SUPPLIER = new Supplier<TreeSet<Module>>() {
- @Override
- public TreeSet<Module> get() {
- return new TreeSet<>(REVISION_COMPARATOR);
- }
- };
-
- private final Map<ModuleIdentifier, String> identifiersToSources;
- private final SetMultimap<URI, Module> namespaceToModules;
- private final SetMultimap<String, Module> nameToModules;
- private final Set<Module> modules;
+ private final Map<ModuleIdentifier, String> identifiersToSources;
+ private final SetMultimap<URI, Module> namespaceToModules;
+ private final SetMultimap<String, Module> nameToModules;
+ private final Set<Module> modules;
SchemaContextImpl(final Set<Module> modules, final Map<ModuleIdentifier, String> identifiersToSources) {
this.identifiersToSources = ImmutableMap.copyOf(identifiersToSources);
- /*
+ /*
* Instead of doing this on each invocation of getModules(), pre-compute
* it once and keep it around -- better than the set we got in.
*/
this.modules = ImmutableSet.copyOf(ModuleDependencySort.sort(modules.toArray(new Module[modules.size()])));
- /*
+ /*
* The most common lookup is from Namespace->Module.
*
* RESTCONF performs lookups based on module name only, where it wants
new TreeMap<URI, Collection<Module>>(), MODULE_SET_SUPPLIER);
final SetMultimap<String, Module> nameMap = Multimaps.newSetMultimap(
new TreeMap<String, Collection<Module>>(), MODULE_SET_SUPPLIER);
+
for (Module m : modules) {
nameMap.put(m.getName(), m);
nsMap.put(m.getNamespace(), m);
}
@Override
- public Set<DataSchemaNode> getDataDefinitions() {
- final Set<DataSchemaNode> dataDefs = new HashSet<>();
- for (Module m : modules) {
- dataDefs.addAll(m.getChildNodes());
- }
- return dataDefs;
- }
-
- @Override
- public Set<Module> getModules() {
- return modules;
- }
-
- @Override
- public Set<NotificationDefinition> getNotifications() {
- final Set<NotificationDefinition> notifications = new HashSet<>();
- for (Module m : modules) {
- notifications.addAll(m.getNotifications());
- }
- return notifications;
- }
-
- @Override
- public Set<RpcDefinition> getOperations() {
- final Set<RpcDefinition> rpcs = new HashSet<>();
- for (Module m : modules) {
- rpcs.addAll(m.getRpcs());
- }
- return rpcs;
- }
-
- @Override
- public Set<ExtensionDefinition> getExtensions() {
- final Set<ExtensionDefinition> extensions = new HashSet<>();
- for (Module m : modules) {
- extensions.addAll(m.getExtensionSchemaNodes());
- }
- return extensions;
- }
-
- @Override
- public Module findModuleByName(final String name, final Date revision) {
- for (final Module module : nameToModules.get(name)) {
- if (revision == null || revision.equals(module.getRevision())) {
- return module;
- }
- }
-
- return null;
- }
-
- @Override
- public Set<Module> findModuleByNamespace(final URI namespace) {
- final Set<Module> ret = namespaceToModules.get(namespace);
- return ret == null ? Collections.<Module>emptySet() : ret;
- }
-
- @Override
- public Module findModuleByNamespaceAndRevision(final URI namespace, final Date revision) {
- if (namespace == null) {
- return null;
- }
- for (Module module : findModuleByNamespace(namespace)) {
- if (revision == null || revision.equals(module.getRevision())) {
- return module;
- }
- }
- return null;
- }
-
- @Override
- public boolean isAugmenting() {
- return false;
- }
-
- @Override
- public boolean isAddedByUses() {
- return false;
- }
-
- @Override
- public boolean isConfiguration() {
- return false;
- }
-
- @Override
- public ConstraintDefinition getConstraints() {
- return null;
- }
-
- @Override
- public QName getQName() {
- return SchemaContext.NAME;
- }
-
- @Override
- public SchemaPath getPath() {
- return SchemaPath.ROOT;
- }
-
- @Override
- public String getDescription() {
- return null;
- }
-
- @Override
- public String getReference() {
- return null;
- }
-
- @Override
- public Status getStatus() {
- return Status.CURRENT;
- }
+ protected Map<ModuleIdentifier, String> getIdentifiersToSources(){
- @Override
- public List<UnknownSchemaNode> getUnknownSchemaNodes() {
- final List<UnknownSchemaNode> result = new ArrayList<>();
- for (Module module : modules) {
- result.addAll(module.getUnknownSchemaNodes());
- }
- return Collections.unmodifiableList(result);
+ return identifiersToSources;
}
@Override
- public Set<TypeDefinition<?>> getTypeDefinitions() {
- final Set<TypeDefinition<?>> result = new LinkedHashSet<>();
- for (Module module : modules) {
- result.addAll(module.getTypeDefinitions());
- }
- return Collections.unmodifiableSet(result);
- }
+ public Set<Module> getModules(){
- @Override
- public Set<DataSchemaNode> getChildNodes() {
- final Set<DataSchemaNode> result = new LinkedHashSet<>();
- for (Module module : modules) {
- result.addAll(module.getChildNodes());
- }
- return Collections.unmodifiableSet(result);
- }
-
- @Override
- public Set<GroupingDefinition> getGroupings() {
- final Set<GroupingDefinition> result = new LinkedHashSet<>();
- for (Module module : modules) {
- result.addAll(module.getGroupings());
- }
- return Collections.unmodifiableSet(result);
- }
-
- @Override
- public DataSchemaNode getDataChildByName(final QName name) {
- for (Module module : modules) {
- final DataSchemaNode result = module.getDataChildByName(name);
- if (result != null) {
- return result;
- }
- }
- return null;
- }
-
- @Override
- public DataSchemaNode getDataChildByName(final String name) {
- for (Module module : modules) {
- final DataSchemaNode result = module.getDataChildByName(name);
- if (result != null) {
- return result;
- }
- }
- return null;
+ return modules;
}
@Override
- public Set<UsesNode> getUses() {
- return Collections.emptySet();
- }
+ protected SetMultimap<URI, Module> getNamespaceToModules() {
- @Override
- public boolean isPresenceContainer() {
- return false;
+ return namespaceToModules;
}
@Override
- public Set<AugmentationSchema> getAvailableAugmentations() {
- return Collections.emptySet();
- }
+ protected SetMultimap<String, Module> getNameToModules() {
- //FIXME: should work for submodules too
- @Override
- public Set<ModuleIdentifier> getAllModuleIdentifiers() {
- return identifiersToSources.keySet();
- }
-
- @Override
- public Optional<String> getModuleSource(final ModuleIdentifier moduleIdentifier) {
- String maybeSource = identifiersToSources.get(moduleIdentifier);
- return Optional.fromNullable(maybeSource);
+ return nameToModules;
}
@Override
public String toString() {
- return "SchemaContextImpl{" +
- "modules=" + modules +
- '}';
+
+ return String.format("SchemaContextImpl{modules=%s}", modules);
}
}
} else if (childNode instanceof Key_stmtContext) {
final Set<String> key = createListKey((Key_stmtContext) childNode);
builder.setKeys(key);
+ } else if (childNode instanceof YangParser.Identifier_stmtContext) {
+ if (childNode.getChild(0).toString().equals("union")) {
+ throw new YangParseException(moduleName, line, "Union statement is not allowed inside a list statement");
+ }
}
}
}
*/
package org.opendaylight.yangtools.yang.parser.repo;
-import com.google.common.base.Objects;
+import com.google.common.base.MoreObjects;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.google.common.collect.ArrayListMultimap;
@Override
public String toString() {
- return Objects.toStringHelper(this)
+ return MoreObjects.toStringHelper(this)
.add("parent", parent)
.toString();
}
package org.opendaylight.yangtools.yang.parser.repo;
import static com.google.common.base.Preconditions.checkArgument;
-
import com.google.common.annotations.Beta;
-import com.google.common.base.Objects.ToStringHelper;
+import com.google.common.base.MoreObjects.ToStringHelper;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
import com.google.common.util.concurrent.CheckedFuture;
import com.google.common.util.concurrent.Futures;
-
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Collection;
import java.util.concurrent.ConcurrentLinkedDeque;
import java.util.concurrent.atomic.AtomicReference;
-
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
import org.opendaylight.yangtools.yang.model.parser.api.YangSyntaxErrorException;
import org.opendaylight.yangtools.yang.model.repo.api.MissingSchemaSourceException;
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.parser.spi.meta;
+
+import com.google.common.base.Predicates;
+import com.google.common.collect.Collections2;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+import java.util.Collection;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
+import org.opendaylight.yangtools.yang.model.api.meta.StatementSource;
+
+/**
+ * Utility abstract base class for implementing declared statements.
+ *
+ *
+ * @param <A> Argument type.
+ */
+public abstract class AbstractDeclaredStatement<A> implements DeclaredStatement<A> {
+
+
+ private final A argument;
+ private final String rawArgument;
+ private final ImmutableList<? extends DeclaredStatement<?>> substatements;
+ private final StatementDefinition definition;
+ private final StatementSource source;
+
+ protected AbstractDeclaredStatement(StmtContext<A,?,?> context) {
+ rawArgument = context.rawStatementArgument();
+ argument = context.getStatementArgument();
+ source = context.getStatementSource();
+ definition = context.getPublicDefinition();
+ /*
+ * Collections.transform could not be used here, since it is lazily
+ * transformed and retains pointer to original collection, which may
+ * contains references to mutable context.
+ *
+ * FluentIterable.tranform().toList() - actually performs transformation
+ * and creates immutable list from transformed results.
+ */
+ substatements = FluentIterable.from(context.declaredSubstatements()).transform(StmtContextUtils.buildDeclared()).toList();
+ }
+
+ protected final <S extends DeclaredStatement<?>> S firstDeclared(Class<S> type) {
+ return type.cast(Iterables.find(substatements, Predicates.instanceOf(type)));
+ }
+
+ @Override
+ public String rawArgument() {
+ return rawArgument;
+ }
+
+ @Override
+ public A argument() {
+ return argument;
+ }
+
+ @Override
+ public StatementDefinition statementDefinition() {
+ return definition;
+ }
+
+ @Override
+ public Collection<? extends DeclaredStatement<?>> declaredSubstatements() {
+ return substatements;
+ }
+
+ @Override
+ public StatementSource getStatementSource() {
+ return source;
+ }
+
+ @SuppressWarnings("unchecked")
+ protected final <S extends DeclaredStatement<?>> Collection<? extends S> allDeclared(Class<S> type) {
+ return Collection.class.cast(Collections2.filter(substatements,Predicates.instanceOf(type)));
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.parser.spi.meta;
+
+import com.google.common.base.Preconditions;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
+import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
+import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
+
+/**
+ *
+ * Class providing necessary support for processing YANG statement.
+ *
+ * This class is intended to be subclassed by developers, which want to
+ * introduce support of statement to parser.
+ *
+ * @param <A>
+ * Argument type
+ * @param <D>
+ * Declared Statement representation
+ * @param <E>
+ * Effective Statement representation
+ */
+public abstract class AbstractStatementSupport<A, D extends DeclaredStatement<A>, E extends EffectiveStatement<A, D>>
+ implements StatementDefinition, StatementFactory<A, D, E>, StatementSupport<A, D, E> {
+
+ private final StatementDefinition type;
+
+ protected AbstractStatementSupport(StatementDefinition publicDefinition) {
+ Preconditions.checkArgument(publicDefinition != this);
+ this.type = Preconditions.checkNotNull(publicDefinition);
+ }
+
+ @Override
+ public final QName getStatementName() {
+ return type.getStatementName();
+ }
+
+ @Override
+ public final QName getArgumentName() {
+ return type.getArgumentName();
+ }
+
+ @Override
+ public final Class<? extends DeclaredStatement<?>> getDeclaredRepresentationClass() {
+ return type.getDeclaredRepresentationClass();
+ }
+
+ @Override
+ public final Class<? extends DeclaredStatement<?>> getEffectiveRepresentationClass() {
+ return type.getEffectiveRepresentationClass();
+ }
+
+ @Override
+ public final StatementDefinition getPublicView() {
+ return type;
+ }
+
+ @Override
+ public abstract A parseArgumentValue(StmtContext<?, ?, ?> ctx, String value) throws SourceException;
+
+ @Override
+ public void onStatementAdded(StmtContext.Mutable<A, D, E> stmt) {
+ // NOOP for most implementations
+ };
+
+ /**
+ *
+ * {@inheritDoc}
+ *
+ * Subclasses of this class may override this method to perform actions on
+ * this event or register modification action using
+ * {@link StmtContext.Mutable#newInferenceAction(ModelProcessingPhase)}.
+ *
+ */
+ @Override
+ public void onLinkageDeclared(StmtContext.Mutable<A, D, E> stmt) throws InferenceException, SourceException {
+ // NOOP for most implementations
+ }
+
+ /**
+ *
+ * {@inheritDoc}
+ *
+ * Subclasses of this class may override this method to perform actions on
+ * this event or register modification action using
+ * {@link StmtContext.Mutable#newInferenceAction(ModelProcessingPhase)}.
+ *
+ */
+ @Override
+ public void onStatementDefinitionDeclared(StmtContext.Mutable<A, D, E> stmt) throws InferenceException,
+ SourceException {
+ // NOOP for most implementations
+ }
+
+ /**
+ *
+ * {@inheritDoc}
+ *
+ * Subclasses of this class may override this method to perform actions on
+ * this event or register modification action using
+ * {@link StmtContext.Mutable#newInferenceAction(ModelProcessingPhase)}.
+ *
+ */
+ @Override
+ public void onFullDefinitionDeclared(StmtContext.Mutable<A, D, E> stmt) throws InferenceException, SourceException {
+ // NOOP for most implementations
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.parser.spi.meta;
+
+import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace;
+
+/**
+ *
+ * Special namespace which allows import of namespaces from other sources.
+ *
+ * <p>
+ * This namespace and its subclasses are used by model processor to
+ * link / import namespaces to context node from supplied {@link StmtContext}.
+ * <p>
+ * This abstraction allows for imports and includes be implement as derived
+ * namespaces of this, but is not tied only for import and include statements.
+ *
+ * @param <K> Imported context identifier
+ */
+public interface ImportedNamespaceContext<K> extends IdentifierNamespace<K, StmtContext<?, ?, ?>> {
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.parser.spi.meta;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
+import org.opendaylight.yangtools.yang.parser.spi.source.StatementSourceReference;
+
+/**
+ *
+ * Thrown when there was inference error
+ *
+ */
+public class InferenceException extends SourceException {
+
+
+ private static final long serialVersionUID = 1L;
+
+ public InferenceException(@Nonnull String message, @Nonnull StatementSourceReference source, Throwable cause) {
+ super(message, source, cause);
+ }
+
+ public InferenceException(@Nonnull String message, @Nonnull StatementSourceReference source) {
+ super(message, source);
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.parser.spi.meta;
+
+import com.google.common.base.Supplier;
+import java.util.Collection;
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
+import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace;
+import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.Mutable;
+
+
+/**
+ * Builder for effective model inference action.
+ *
+ * Model inference action is core principle of transforming
+ * declared model into effective model.
+ *
+ * Since YANG allows forward references, some inference actions
+ * needs to be taken at later point, where reference is actually
+ * resolved. Referenced objects are not retrieved directly
+ * but are represented as {@link Prerequisite} (prerequisite) for
+ * inference action to be taken.
+ *
+ * Some existing YANG statements are more complex and also object,
+ * for which effective model may be inferred is also represented
+ * as {@link Prerequisite} which once, when reference is available
+ * will contain target context, which may be used for inference
+ * action.
+ *
+ * <h2>Implementing inference action</h2>
+ *
+ * Effective inference action could always be splitted into two
+ * separate tasks:
+ * <ol>
+ * <li>Declaration of inference action and its prerequisites</li>
+ * <li>Execution of inference action</li>
+ * </ol>
+ * In order to declare inference action following steps needs
+ * to be taken:
+ *
+ * <ol>
+ * <li>Use {@link StmtContext.Mutable#newInferenceAction(ModelProcessingPhase)} to obtain
+ * {@link ModelActionBuilder}.
+ * <li>Use builder to specify concrete prerequisites of inference action
+ * (other statements, values from identifier namespaces)
+ * <li>Use builder to specify concrete set of nodes (or forward references to nodes)
+ * which will inference action mutate.
+ * <li>Use {@link #apply(InferenceAction)} with {@link InferenceAction} implementation
+ * to register inference action.
+ * </ol>
+ *
+ * Action will be executed when:
+ * <ul>
+ * <li> {@link InferenceAction#apply()} - all prerequisites (and declared forward references) are met,
+ * action could dereference them and start applying changes.
+ * </li>
+ * <li>{@link InferenceAction#prerequisiteFailed(Collection)} - semantic parser finished all other satisfied
+ * inference actions and some of declared prerequisites was still not met.
+ * </li>
+ * </ul>
+ *
+ * TODO: Insert real word example
+ *
+ * <h2>Design notes</h2>
+ * {@link java.util.concurrent.Future} seems as viable and more standard
+ * alternative to {@link Prerequisite}, but futures also carries
+ * promise that resolution of it is carried in other
+ * thread, which will actually put additional constraints on
+ * semantic parser.
+ *
+ * Also listening on multiple futures is costly, so we opted
+ * out of future and designed API, which later may introduce
+ * futures.
+ *
+ */
+public interface ModelActionBuilder {
+
+ public interface Prerequisite<T> extends Supplier<T> {
+
+ /**
+ *
+ * Returns associated prerequisite once it is resolved.
+ *
+ * @return associated prerequisite once it is resolved.
+ *
+ */
+ @Override
+ public T get();
+
+ boolean isDone();
+
+ }
+
+ /**
+ * User-defined inference action.
+ *
+ */
+ public interface InferenceAction {
+
+ /**
+ * Invoked once all prerequisites were met and forward references
+ * were resolved and inference action should be applied.
+ *
+ * Implementors may do necessary changes to mutable objects
+ * which were declared.
+ *
+ * @throws InferenceException If inference action can not be processed.
+ * Note that this exception be used for user to debug YANG sources,
+ * so should provide helpful context to fix issue in sources.
+ */
+ void apply() throws InferenceException;
+
+ /**
+ * Invoked once one of prerequisites was not met,
+ * even after all other satifiable inference actions were processed.
+ *
+ * Implementors MUST throw {@link InferenceException} if semantic processing
+ * of model should be stopped and failed.
+ *
+ * List of failed prerequisites should be used to select right message / error
+ * type to debug problem in YANG sources.
+ *
+ * @throws InferenceException If inference action can not be processed.
+ * Note that this exception be used for user to debug YANG sources,
+ * so should provide helpful context to fix issue in sources.
+ */
+ void prerequisiteFailed(Collection<? extends Prerequisite<?>> failed) throws InferenceException;
+ }
+
+ @Nonnull <D extends DeclaredStatement<?>> Prerequisite<D> requiresDeclared(StmtContext<?,? extends D,?> context);
+
+ @Nonnull <K, D extends DeclaredStatement<?>, N extends StatementNamespace<K, ? extends D, ?>> Prerequisite<D> requiresDeclared(StmtContext<?,?,?> context,Class<N> namespace, K key);
+
+ @Nonnull <K, D extends DeclaredStatement<?>, N extends StatementNamespace<K, ? extends D, ?>> Prerequisite<StmtContext<?, D, ?>>requiresDeclaredCtx(StmtContext<?,?,?> context,Class<N> namespace, K key);
+
+ @Nonnull <E extends EffectiveStatement<?,?>> Prerequisite<E> requiresEffective(StmtContext<?,?,? extends E> stmt);
+
+ @Nonnull <K, E extends EffectiveStatement<?, ?>, N extends StatementNamespace<K, ?, ? extends E>> Prerequisite<E> requiresEffective(StmtContext<?,?,?> context,Class<N> namespace, K key);
+
+ @Nonnull <K, E extends EffectiveStatement<?, ?>, N extends StatementNamespace<K, ?, ? extends E>> Prerequisite<StmtContext<?,?,E>> requiresEffectiveCtx(StmtContext<?,?,?> context,Class<N> namespace, K key);
+
+ @Nonnull <N extends IdentifierNamespace<? ,?>> Prerequisite<Mutable<?,?,?>> mutatesNs(Mutable<?,?, ?> ctx, Class<N> namespace);
+
+ @Nonnull <T extends Mutable<?,?,?>> Prerequisite<T> mutatesEffectiveCtx(T stmt);
+
+ @Nonnull <K,E extends EffectiveStatement<?,?>,N extends StatementNamespace<K, ?, ? extends E>> Prerequisite<Mutable<?,?,E>> mutatesEffectiveCtx(StmtContext<?,?,?> context,Class<N> namespace, K key);
+
+ void apply(InferenceAction action) throws InferenceException;
+
+ @Nonnull <A,D extends DeclaredStatement<A>,E extends EffectiveStatement<A, D>> Prerequisite<StmtContext<A, D, E>> requiresCtx(StmtContext<A, D, E> context, ModelProcessingPhase phase);
+
+ @Nonnull <K, N extends StatementNamespace<K, ?, ? >> Prerequisite<StmtContext<?,?,?>> requiresCtx(StmtContext<?, ?, ?> context, Class<N> namespace, K key, ModelProcessingPhase phase);
+
+ @Nonnull <C extends StmtContext.Mutable<?,?,?>, CT extends C> Prerequisite<C> mutatesCtx(CT root, ModelProcessingPhase phase);
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.parser.spi.meta;
+
+import javax.annotation.Nullable;
+
+public enum ModelProcessingPhase {
+
+ /**
+ *
+ * Cross-source relationship resolution phase.
+ * <p>
+ * In this phase of processing only statements which affects
+ * cross-source relationship (e.g. imports / includes)
+ * are processed.
+ * <p>
+ * At end of this phase all source related contexts should
+ * be bind to their imports and includes to allow
+ * visibility of custom defined statements in following
+ * phases.
+ */
+ SourceLinkage(null),
+ StatementDefinition(SourceLinkage),
+ FullDeclaration(StatementDefinition),
+ EffectiveModel(FullDeclaration);
+
+
+ private final ModelProcessingPhase previousPhase;
+
+ private ModelProcessingPhase(@Nullable ModelProcessingPhase previous) {
+ this.previousPhase = previous;
+ }
+
+ public ModelProcessingPhase getPreviousPhase() {
+ return previousPhase;
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.parser.spi.meta;
+
+import com.google.common.base.Preconditions;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import org.opendaylight.yangtools.concepts.Identifiable;
+import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace;
+
+/**
+ * Definition / implementation of specific Identifier Namespace behaviour.
+ *
+ * Namespace behaviour is build on top of tree of {@link NamespaceStorageNode}
+ * which represents local context of one of types defined in {@link StorageNodeType}.
+ *
+ * For common behaviour models please use static factories {@link #global(Class)},
+ * {@link #sourceLocal(Class)} and {@link #treeScoped(Class)}.
+ *
+ * @param <K> Key type
+ * @param <V> Value type
+ * @param <N> Namespace Type
+ */
+public abstract class NamespaceBehaviour<K,V, N extends IdentifierNamespace<K, V>> implements Identifiable<Class<N>>{
+
+ public enum StorageNodeType {
+ Global,
+ SourceLocalSpecial,
+ StatementLocal
+ }
+
+ public interface Registry {
+
+ abstract <K, V, N extends IdentifierNamespace<K, V>> NamespaceBehaviour<K, V, N> getNamespaceBehaviour(Class<N> type);
+
+ }
+
+ public interface NamespaceStorageNode {
+
+ StorageNodeType getStorageNodeType();
+
+ @Nullable NamespaceStorageNode getParentNamespaceStorage();
+
+ @Nullable <K, V, N extends IdentifierNamespace<K, V>> V getFromLocalStorage(Class<N> type, K key);
+
+ @Nullable <K, V, N extends IdentifierNamespace<K, V>> void addToLocalStorage(Class<N> type, K key, V value);
+
+ }
+
+ private final Class<N> identifier;
+
+
+ protected NamespaceBehaviour(Class<N> identifier) {
+ this.identifier = Preconditions.checkNotNull(identifier);
+ }
+
+ /**
+ *
+ * Creates global namespace behaviour for supplied namespace type.
+ *
+ * Global behaviour stores and loads all values from root {@link NamespaceStorageNode}
+ * with type of {@link StorageNodeType#Global}.
+ *
+ * @param identifier Namespace identifier.
+ * @return global namespace behaviour for supplied namespace type.
+ */
+ public static @Nonnull <K,V, N extends IdentifierNamespace<K, V>> NamespaceBehaviour<K,V,N> global(Class<N> identifier) {
+ return new StorageSpecific<>(identifier, StorageNodeType.Global);
+ }
+
+ /**
+ *
+ * Creates source-local namespace behaviour for supplied namespace type.
+ *
+ * Source-local namespace behaviour stores and loads all values from closest
+ * {@link NamespaceStorageNode} ancestor with type of
+ * {@link StorageNodeType#SourceLocalSpecial}.
+ *
+ * @param identifier Namespace identifier.
+ * @return source-local namespace behaviour for supplied namespace type.
+ */
+ public static <K,V, N extends IdentifierNamespace<K, V>> NamespaceBehaviour<K,V,N> sourceLocal(Class<N> identifier) {
+ return new StorageSpecific<>(identifier, StorageNodeType.SourceLocalSpecial);
+ }
+
+ /**
+ *
+ * Creates tree-scoped namespace behaviour for supplied namespace type.
+ *
+ * Tree-scoped namespace behaviour search for value in all storage nodes
+ * up to the root and stores values in supplied node.
+ *
+ * @param identifier Namespace identifier.
+ * @return tree-scoped namespace behaviour for supplied namespace type.
+ */
+ public static <K,V, N extends IdentifierNamespace<K, V>> NamespaceBehaviour<K,V,N> treeScoped(Class<N> identifier) {
+ return new TreeScoped<>(identifier);
+ }
+
+ public abstract V getFrom(NamespaceStorageNode storage, K key);
+ public abstract void addTo(NamespaceStorageNode storage,K key,V value);
+
+
+ @Override
+ public Class<N> getIdentifier() {
+ return identifier;
+ }
+
+ protected final V getFromLocalStorage(NamespaceStorageNode storage, K key) {
+ return storage.getFromLocalStorage(getIdentifier(), key);
+ }
+
+ protected final void addToStorage(NamespaceStorageNode storage,K key,V value) {
+ storage.addToLocalStorage(getIdentifier(),key,value);
+ }
+
+ static class StorageSpecific<K,V, N extends IdentifierNamespace<K, V>> extends NamespaceBehaviour<K, V, N> {
+
+ StorageNodeType storageType;
+
+ public StorageSpecific(Class<N> identifier, StorageNodeType type) {
+ super(identifier);
+ storageType = Preconditions.checkNotNull(type);
+ }
+
+ @Override
+ public V getFrom(final NamespaceStorageNode storage, final K key) {
+ NamespaceStorageNode current = storage;
+ while(current.getParentNamespaceStorage() != null) {
+ current = current.getParentNamespaceStorage();
+ }
+ return getFromLocalStorage(current,key);
+ }
+
+ @Override
+ public void addTo(NamespaceBehaviour.NamespaceStorageNode storage, K key, V value) {
+ NamespaceStorageNode current = storage;
+ while(current.getStorageNodeType() != storageType) {
+ current = current.getParentNamespaceStorage();
+ }
+ addToStorage(current, key, value);
+ }
+
+ }
+
+ static class TreeScoped<K,V, N extends IdentifierNamespace<K, V>> extends NamespaceBehaviour<K, V, N> {
+
+ public TreeScoped(Class<N> identifier) {
+ super(identifier);
+ }
+
+ @Override
+ public V getFrom(final NamespaceStorageNode storage, final K key) {
+ NamespaceStorageNode current = storage;
+ while(current != null) {
+ final V val = getFromLocalStorage(current, key);
+ if(val != null) {
+ return val;
+ }
+ current = current.getParentNamespaceStorage();
+ }
+ return null;
+ }
+
+ @Override
+ public void addTo(NamespaceStorageNode storage,K key, V value) {
+ addToStorage(storage, key, value);
+ }
+
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.parser.spi.meta;
+
+import com.google.common.base.Preconditions;
+
+/**
+ *
+ * Thrown when identifier namespace is not available (supported)
+ * in specific model processing phase.
+ *
+ */
+public class NamespaceNotAvailableException extends RuntimeException {
+
+ private static final long serialVersionUID = 1L;
+
+ public NamespaceNotAvailableException(String message) {
+ super(Preconditions.checkNotNull(message));
+ }
+
+ public NamespaceNotAvailableException(String message, Throwable cause) {
+ super(Preconditions.checkNotNull(message), cause);
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.parser.spi.meta;
+
+import com.google.common.base.Preconditions;
+
+
+public class ReactorException extends Exception {
+
+ private static final long serialVersionUID = 1L;
+ private final ModelProcessingPhase phase;
+
+ public ReactorException(ModelProcessingPhase phase, String message, Throwable cause) {
+ super(message, cause);
+ this.phase = Preconditions.checkNotNull(phase);
+ }
+
+ public ReactorException(ModelProcessingPhase phase, String message) {
+ super(message);
+ this.phase = Preconditions.checkNotNull(phase);
+ }
+
+ public final ModelProcessingPhase getPhase() {
+ return phase;
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.parser.spi.meta;
+
+public class SomeModifiersUnresolvedException extends ReactorException {
+
+ private static final long serialVersionUID = 1L;
+
+ public SomeModifiersUnresolvedException(ModelProcessingPhase phase) {
+ super(phase,"Some of " + phase + " modifiers for statements were not resolved.");
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.parser.spi.meta;
+
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
+
+public interface StatementFactory<A,D extends DeclaredStatement<A>,E extends EffectiveStatement<A, D>> {
+
+ D createDeclared(StmtContext<A,D,?> ctx);
+
+ E createEffective(StmtContext<A,D,E> ctx);
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.parser.spi.meta;
+
+import javax.annotation.Nullable;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
+import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace;
+
+public interface StatementNamespace<K, D extends DeclaredStatement<?>,E extends EffectiveStatement<?,D>> extends IdentifierNamespace<K, E> {
+
+ @Override
+ @Nullable E get(K key);
+
+ public interface TreeScoped<K, D extends DeclaredStatement<?>,E extends EffectiveStatement<?,D>> extends StatementNamespace<K,D,E> {
+
+ TreeScoped<K,D,E> getParentContext();
+
+ }
+
+ public interface TreeBased<K,D extends DeclaredStatement<?>,E extends EffectiveStatement<?,D>> {
+
+ }
+
+
+}
--- /dev/null
+package org.opendaylight.yangtools.yang.parser.spi.meta;
+
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
+import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
+import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
+
+/**
+ *
+ * Support for processing concrete YANG statement.
+ *
+ * This interface is intended to be implemented by developers, which want to
+ * introduce support of statement to parser. Consider subclassing
+ * {@link AbstractStatementSupport} for easier implementation of this interface.
+ *
+ * @param <A>
+ * Argument type
+ * @param <D>
+ * Declared Statement representation
+ * @param <E>
+ * Effective Statement representation
+ */
+public interface StatementSupport<A, D extends DeclaredStatement<A>, E extends EffectiveStatement<A, D>> extends StatementDefinition, StatementFactory<A, D, E> {
+
+ /**
+ * Returns public statement definition, which will be present in builded statements.
+ *
+ * Public statement definition may be used to provide different implementation
+ * of statement definition, which will not retain any build specific data
+ * or context.
+ *
+ * @return public statement definition, which will be present in builded statements.
+ */
+ StatementDefinition getPublicView();
+
+ /**
+ *
+ * Parses textual representation of argument in object representation.
+ *
+ * @param ctx Context, which may be used to access source-specific namespaces
+ * required for parsing.
+ * @param value String representation of value, as was present in text source.
+ * @return Parsed value
+ */
+ A parseArgumentValue(StmtContext<?, ?, ?> ctx, String value) throws SourceException;
+
+ /**
+ *
+ * Invoked when statement is added to build context.
+ *
+ * @param stmt
+ * Context of added statement. No substatement are available.
+ */
+ void onStatementAdded(StmtContext.Mutable<A, D, E> stmt);
+
+ /**
+ *
+ * Invoked when statement is closed during
+ * {@link ModelProcessingPhase#StatementDefinition} phase.
+ *
+ * Invoked when statement is closed during
+ * {@link ModelProcessingPhase#StatementDefinition} phase, only substatements from
+ * this and previous phase are available.
+ *
+ * Implementation may use method to perform actions on this event or
+ * register modification action using
+ * {@link StmtContext.Mutable#newInferenceAction(ModelProcessingPhase)}.
+ *
+ * @param stmt
+ * Context of added statement.
+ */
+ void onLinkageDeclared(StmtContext.Mutable<A, D, E> stmt) throws InferenceException,
+ SourceException;
+
+ /**
+ *
+ * Invoked when statement is closed during
+ * {@link ModelProcessingPhase#StatementDefinition} phase.
+ *
+ * Invoked when statement is closed during
+ * {@link ModelProcessingPhase#StatementDefinition} phase, only substatements from
+ * this phase are available.
+ *
+ * Implementation may use method to perform actions on this event or
+ * register modification action using
+ * {@link StmtContext.Mutable#newInferenceAction(ModelProcessingPhase)}.
+ *
+ * @param stmt
+ * Context of added statement. Argument and statement parent is
+ * accessible.
+ */
+ void onStatementDefinitionDeclared(StmtContext.Mutable<A, D, E> stmt) throws InferenceException,
+ SourceException;
+
+ /**
+ *
+ * Invoked when statement is closed during
+ * {@link ModelProcessingPhase#FullDeclaration} phase.
+ *
+ * Invoked when statement is closed during
+ * {@link ModelProcessingPhase#FullDeclaration} phase, only substatements
+ * from this phase are available.
+ *
+ * Implementation may use method to perform actions on this event or
+ * register modification action using
+ * {@link StmtContext.Mutable#newInferenceAction(ModelProcessingPhase)}.
+ *
+ *
+ * @param stmt
+ * Context of added statement. Argument and statement parent is
+ * accessible.
+ */
+ void onFullDefinitionDeclared(StmtContext.Mutable<A, D, E> stmt) throws InferenceException,
+ SourceException;
+
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.parser.spi.meta;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableMap;
+import java.util.HashMap;
+import java.util.Map;
+import org.opendaylight.yangtools.concepts.Immutable;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace;
+
+public final class StatementSupportBundle implements Immutable,NamespaceBehaviour.Registry {
+
+ private static final StatementSupportBundle EMPTY = new StatementSupportBundle(null, ImmutableMap.<QName, StatementSupport<?, ?, ?>>of(), ImmutableMap.<Class<?>, NamespaceBehaviour<?, ?, ?>>of());
+
+ private final StatementSupportBundle parent;
+ private final ImmutableMap<QName, StatementSupport<?,?,?>> definitions;
+ private final ImmutableMap<Class<?>, NamespaceBehaviour<?, ?, ?>> namespaceDefinitions;
+
+ private StatementSupportBundle(StatementSupportBundle parent,
+ ImmutableMap<QName, StatementSupport<?, ?, ?>> statements,
+ ImmutableMap<Class<?>, NamespaceBehaviour<?, ?, ?>> namespaces) {
+ this.parent = parent;
+ this.definitions = statements;
+ this.namespaceDefinitions = namespaces;
+ }
+
+ public static final Builder builder() {
+ return new Builder(EMPTY);
+ }
+
+ public static final Builder derivedFrom(StatementSupportBundle parent) {
+ return new Builder(parent);
+ }
+
+ @Override
+ public <K, V, N extends IdentifierNamespace<K, V>> NamespaceBehaviour<K, V, N> getNamespaceBehaviour(Class<N> namespace)
+ throws NamespaceNotAvailableException {
+ NamespaceBehaviour<?, ?, ?> potential = namespaceDefinitions.get(namespace);
+ if (potential != null) {
+ Preconditions.checkState(namespace.equals(potential.getIdentifier()));
+
+ /*
+ * Safe cast, previous checkState checks equivalence of key from
+ * which type argument are derived
+ */
+ @SuppressWarnings("unchecked")
+ NamespaceBehaviour<K, V, N> casted = (NamespaceBehaviour<K, V, N>) potential;
+ return casted;
+ }
+ if (parent != null) {
+ return parent.getNamespaceBehaviour(namespace);
+ }
+ return null;
+ }
+
+ public <K, V, N extends IdentifierNamespace<K, V>> boolean hasNamespaceBehaviour(Class<N> namespace) {
+ if (namespaceDefinitions.containsKey(namespace)) {
+ return true;
+ }
+ if (parent != null) {
+ return parent.hasNamespaceBehaviour(namespace);
+ }
+ return false;
+ }
+
+ public StatementSupport<?, ?,?> getStatementDefinition(QName stmtName) {
+ StatementSupport<?,?, ?> potential = definitions.get(stmtName);
+ if (potential != null) {
+ return potential;
+ }
+ if (parent != null) {
+ return parent.getStatementDefinition(stmtName);
+ }
+ return null;
+ }
+
+ public static class Builder implements org.opendaylight.yangtools.concepts.Builder<StatementSupportBundle> {
+
+ private final StatementSupportBundle parent;
+ private final Map<QName, StatementSupport<?,?,?>> statements = new HashMap<>();
+ private final Map<Class<?>, NamespaceBehaviour<?, ?, ?>> namespaces = new HashMap<>();
+
+ Builder(StatementSupportBundle parent) {
+ this.parent = parent;
+ }
+
+ public Builder addSupport(StatementSupport<?, ?,?> definition) {
+ QName identifier = definition.getStatementName();
+ Preconditions.checkState(!statements.containsKey(identifier), "Statement %s already defined.",identifier);
+ Preconditions.checkState(parent.getStatementDefinition(identifier) == null, "Statement %s already defined.",identifier);
+ statements.put(identifier, definition);
+ return this;
+ }
+
+ public <K, V, N extends IdentifierNamespace<K, V>> Builder addSupport(NamespaceBehaviour<K, V, N> namespaceSupport) {
+ Class<N> identifier = namespaceSupport.getIdentifier();
+ Preconditions.checkState(!namespaces.containsKey(identifier));
+ Preconditions.checkState(!parent.hasNamespaceBehaviour(identifier));
+ namespaces.put(identifier, namespaceSupport);
+ return this;
+ }
+
+ @Override
+ public StatementSupportBundle build() {
+ return new StatementSupportBundle(parent, ImmutableMap.copyOf(statements), ImmutableMap.copyOf(namespaces));
+ }
+
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.parser.spi.meta;
+
+import java.util.Collection;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
+import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace;
+import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
+import org.opendaylight.yangtools.yang.model.api.meta.StatementSource;
+import org.opendaylight.yangtools.yang.parser.spi.source.StatementSourceReference;
+
+
+public interface StmtContext<A,D extends DeclaredStatement<A>, E extends EffectiveStatement<A, D>> {
+
+ @Nonnull StatementSource getStatementSource();
+
+ @Nonnull StatementSourceReference getStatementSourceReference();
+
+ @Nonnull StatementDefinition getPublicDefinition();
+
+ @Nullable StmtContext<?,?,?> getParentContext();
+
+ @Nullable String rawStatementArgument();
+
+ @Nullable A getStatementArgument();
+
+ @Nonnull <K,VT, V extends VT,N extends IdentifierNamespace<K, V>> VT getFromNamespace(Class<N> type, K key) throws NamespaceNotAvailableException;
+
+ @Nonnull StmtContext<?,?,?> getRoot();
+
+ @Nonnull Collection<? extends StmtContext<?,?,?>> declaredSubstatements();
+
+ D buildDeclared();
+
+ E buildEffective();
+
+ interface Mutable<A,D extends DeclaredStatement<A>,E extends EffectiveStatement<A, D>> extends StmtContext<A,D,E> {
+
+ @Override
+ StmtContext.Mutable<?,?,?> getParentContext();
+
+ <K,V,VT extends V,N extends IdentifierNamespace<K, V>> void addToNs(Class<N> type, K key, VT value) throws NamespaceNotAvailableException;
+
+ @Override
+ StmtContext.Mutable<?,?,?> getRoot();
+
+ ModelActionBuilder newInferenceAction(ModelProcessingPhase phase);
+
+ <K,KT extends K, N extends StatementNamespace<K, ?, ?>> void addContext(Class<N> namepsace, KT key,
+ StmtContext<?, ?, ?> stmt);
+
+ }
+
+
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.parser.spi.meta;
+
+import com.google.common.base.Function;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
+
+public final class StmtContextUtils {
+
+ private static final Function<StmtContext<?, ?,?>, DeclaredStatement<?>> BUILD_DECLARED = new Function<StmtContext<?,?,?>, DeclaredStatement<?>>() {
+
+ @Override
+ public DeclaredStatement<?> apply(StmtContext<?,?,?> input) {
+ return input.buildDeclared();
+ }
+
+ };
+
+ private static final Function<StmtContext<?, ?,?>, EffectiveStatement<?,?>> BUILD_EFFECTIVE = new Function<StmtContext<?,?,?>, EffectiveStatement<?,?>>() {
+
+ @Override
+ public EffectiveStatement<?,?> apply(StmtContext<?,?,?> input) {
+ return input.buildEffective();
+ }
+
+ };
+
+ private StmtContextUtils() {
+ throw new UnsupportedOperationException("Utility class");
+ }
+
+
+ @SuppressWarnings("unchecked")
+ public static final <D extends DeclaredStatement<?>> Function<StmtContext<?, ? extends D, ?>, D> buildDeclared() {
+ return Function.class.cast(BUILD_DECLARED);
+ }
+
+ @SuppressWarnings("unchecked")
+ public static final <E extends EffectiveStatement<?,?>> Function<StmtContext<?, ?,? extends E>, E> buildEffective() {
+ return Function.class.cast(BUILD_EFFECTIVE);
+ }
+
+ @SuppressWarnings("unchecked")
+ public static final <AT,DT extends DeclaredStatement<AT>> AT firstAttributeOf(Iterable<? extends StmtContext<?,?,?>> contexts, Class<DT> declaredType) {
+ for(StmtContext<?, ?, ?> ctx : contexts) {
+ if(producesDeclared(ctx,declaredType)) {
+ return (AT) ctx.getStatementArgument();
+ }
+ }
+ return null;
+ }
+
+ public static final boolean producesDeclared(StmtContext<?, ?, ?> ctx, Class<? extends DeclaredStatement<?>> type) {
+ return type.isAssignableFrom(ctx.getPublicDefinition().getDeclaredRepresentationClass());
+ }
+
+
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.parser.spi.source;
+
+import org.opendaylight.yangtools.yang.model.api.meta.StatementSource;
+
+/**
+ *
+ * Reference of statement source present in textual source format
+ *
+ * Utility implementation of {@link StatementSourceReference} for textual sources,
+ * this is prefered {@link StatementSourceReference} for implementations
+ * of YANG / YIN statement stream sources.
+ *
+ *
+ * To create source reference use one of this static factiories:
+ * <ul>
+ * <li>{@link #atPosition(String, int, int)} - provides most specific reference of statement location,
+ * this is most prefered since it provides most context to debug YANG model.
+ * </li>
+ * <li>{@link #atLine(String, int)}- provides source and line of statement location.
+ * </li>
+ * <li>{@link #inSource(String)} - least specific reference, should be used only if any of previous
+ * references are unable to create / derive from source.
+ * </li>
+ * </ul>
+ *
+ */
+public abstract class DeclarationInTextSource implements StatementSourceReference {
+
+ private final String source;
+
+ DeclarationInTextSource(String source) {
+ this.source = source;
+ }
+
+ public String getSourceName() {
+ return source;
+ }
+
+ @Override
+ public StatementSource getStatementSource() {
+ return StatementSource.DECLARATION;
+ }
+
+ @Override
+ public abstract String toString();
+
+ public static final DeclarationInTextSource inSource(String sourceName) {
+ return new InSource(sourceName);
+ }
+
+ public static final DeclarationInTextSource atLine(String sourceName, int line) {
+ return new AtLine(sourceName,line);
+ }
+
+ public static final DeclarationInTextSource atPosition(String sourceName, int line, int position) {
+ return new AtPosition(sourceName,line,position);
+ }
+
+ private static class InSource extends DeclarationInTextSource {
+
+ public InSource(String source) {
+ super(source);
+ }
+
+ @Override
+ public String toString() {
+ return getSourceName();
+ }
+
+ }
+
+ private static class AtLine extends DeclarationInTextSource {
+
+ private final int line;
+
+ public AtLine(String source,int line) {
+ super(source);
+ this.line = line;
+ }
+
+ @Override
+ public String toString() {
+ return String.format("%s:%d", getSourceName(),line);
+ }
+
+ }
+
+ private static class AtPosition extends DeclarationInTextSource {
+
+ private int line;
+ private int character;
+
+ public AtPosition(String source, int line, int character) {
+ super(source);
+ this.line = line;
+ this.character = character;
+ }
+
+ @Override
+ public String toString() {
+ return String.format("%s:%d:%d", getSourceName(),line,character);
+ }
+
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.parser.spi.source;
+
+import javax.annotation.Nullable;
+import org.opendaylight.yangtools.yang.common.QNameModule;
+import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace;
+
+/**
+ *
+ * Source-specific mapping of prefixes to namespaces
+ *
+ */
+public interface PrefixToModule extends IdentifierNamespace<String, QNameModule> {
+
+ public static final String DEFAULT_PREFIX = "";
+
+
+ /**
+ *
+ * Returns QNameModule (namespace + revision) associated with supplied
+ * prefix.
+ *
+ * @param prefix
+ * Prefix
+ * @return QNameModule associated with supplied prefix, or null if prefix is
+ * not defined.
+ *
+ */
+ @Override
+ @Nullable QNameModule get(String prefix);
+
+ /**
+ *
+ * Returns QNameModule (namespace + revision) associated with XML namespace
+ * (URI).
+ *
+ * @param namespace
+ * XML Namespace
+ * @return QNameModule associated with supplied namespace, or null if prefix
+ * is not defined.
+ *
+ */
+ @Nullable QNameModule getByNamespace(String namespace);
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.parser.spi.source;
+
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace;
+import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
+
+/**
+ *
+ * Map of fully qualified statement name to statement definition.
+ *
+ */
+public interface QNameToStatementDefinition extends IdentifierNamespace<QName, StatementDefinition> {
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.parser.spi.source;
+
+import com.google.common.base.Preconditions;
+import javax.annotation.Nonnull;
+
+/**
+ *
+ * Thrown to indicate error in YANG model source.
+ *
+ */
+public class SourceException extends Exception {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
+
+ private final StatementSourceReference sourceRef;
+
+ public SourceException(@Nonnull String message,@Nonnull StatementSourceReference source) {
+ super(Preconditions.checkNotNull(message));
+ sourceRef = Preconditions.checkNotNull(source);
+ }
+
+ public SourceException(@Nonnull String message,@Nonnull StatementSourceReference source, Throwable cause) {
+ super(Preconditions.checkNotNull(message),cause);
+ sourceRef = Preconditions.checkNotNull(source);
+ }
+
+ public @Nonnull StatementSourceReference getSourceReference() {
+ return sourceRef;
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.parser.spi.source;
+
+import org.opendaylight.yangtools.yang.model.api.meta.StatementSource;
+
+/**
+ *
+ * Reference of statement source
+ *
+ * Statement source reference serves to provide information, why
+ * statement was defined and introduced in model.
+ *
+ * Reasons for introduction of statement could be various, but
+ * most obvious one is explicit declaration in model source text
+ * such as {@link DeclarationInTextSource}.
+ *
+ */
+public interface StatementSourceReference {
+
+ /**
+ *
+ * Returns source type
+ *
+ * @return {@link StatementSource#DECLARATION} if statement was explicitly
+ * declared in YANG model source, {@link StatementSource#CONTEXT} if statement
+ * was inferred.
+ */
+ StatementSource getStatementSource();
+
+ /**
+ * Returns human readable representation of statement source.
+ *
+ * Implementations of this interface should override {@link #toString()},
+ * since it may be used in error reporting to provide context
+ * information for model designer to debug errors in its mode.
+ *
+ * @return human readable representation of statement source.
+ */
+ @Override
+ String toString();
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.parser.spi.source;
+
+/**
+ *
+ * Statement stream source, which is used for inference of effective model.
+ *
+ * <p>
+ * Statement stream source is required to emit its statements using supplied
+ * {@link StatementWriter}.
+ * </p>
+ * <p>
+ * Since YANG allows language extensions defined in sources (which defines how
+ * source is serialized), instances of extensions present anywhere and forward
+ * references, each source needs to be processed in three steps, where each step
+ * uses different set of supported statements.
+ * <p>
+ * Steps (in order of invocation) are:
+ *
+ * <ol>
+ * <li>{@link #writeLinkage(StatementWriter, QNameToStatementDefinition)} -
+ * Source MUST emit only statements related in linkage, which are present in
+ * supplied statement definition map. This step is used to build cross-source
+ * linkage and visibility relationship, and to determine XMl namespaces and
+ * prefixes.</li>
+ * <li>
+ * {@link #writeLinkageAndStatementDefinitions(StatementWriter, QNameToStatementDefinition, PrefixToModule)}
+ * - Source MUST emit only statements related to linkage and language extensions
+ * definitions, which are present in supplied statement definition map. This
+ * step is used to build statement definitions in order to fully processed
+ * source.</li>
+ * <li>
+ * {@link #writeFull(StatementWriter, QNameToStatementDefinition, PrefixToModule)}
+ * - Source MUST emit all statements present in source. This step is used to
+ * build full declared statement model of source.</li>
+ * </ol>
+ *
+ */
+public interface StatementStreamSource {
+
+ /**
+ *
+ * Emits only linkage-related statements to supplied {@code writer}.
+ *
+ * @param writer
+ * {@link StatementWriter} which should be used to emit
+ * statements.
+ * @param stmtDef
+ * Map of available statement definitions. Only these statements
+ * may be written to statement writer, source MUST ignore and MUST NOT
+ * emit any other statements.
+ *
+ * @throws SourceException
+ * If source was is not valid, or provided statement writer
+ * failed to write statements.
+ */
+ void writeLinkage(StatementWriter writer, QNameToStatementDefinition stmtDef) throws SourceException;
+
+ /**
+ *
+ * Emits only linkage and language extension statements to supplied
+ * {@code writer}.
+ *
+ * @param writer
+ * {@link StatementWriter} which should be used to emit
+ * statements.
+ * @param stmtDef
+ * Map of available statement definitions. Only these statements
+ * may be written to statement writer, source MUST ignore and MUST NOT
+ * emit any other statements.
+ * @param prefixes
+ * Map of source-specific prefixes to namespaces
+ *
+ * @throws SourceException
+ * If source was is not valid, or provided statement writer
+ * failed to write statements.
+ */
+ void writeLinkageAndStatementDefinitions(StatementWriter writer, QNameToStatementDefinition stmtDef, PrefixToModule prefixes) throws SourceException;
+
+ /**
+ *
+ * Emits every statements present in this statement source to supplied
+ * {@code writer}.
+ *
+ * @param writer
+ * {@link StatementWriter} which should be used to emit
+ * statements.
+ * @param stmtDef
+ * Map of available statement definitions.
+ * @param prefixes
+ * Map of source-specific prefixes to namespaces
+ * @throws SourceException
+ * If source was is not valid, or provided statement writer
+ * failed to write statements.
+ */
+ void writeFull(StatementWriter writer,QNameToStatementDefinition stmtDef, PrefixToModule prefixes) throws SourceException;
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.parser.spi.source;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.common.QName;
+
+public interface StatementWriter {
+
+ /**
+ *
+ * Starts statement with supplied name and location in source.
+ *
+ *
+ * <p>
+ * Each started statement must also be closed by
+ * {@link #endStatement(StatementSourceReference)} in order for stream to be
+ * correct.
+ * </p>
+ * <p>
+ * If statement requires an argument, user must call
+ * {@link #argumentValue(String, StatementSourceReference)} to emit
+ * argument, otherwise any subsequent call to this {@link StatementWriter}
+ * will throw {@link SourceException}.
+ * </p>
+ * <p>
+ * If statement has substatements, in order to start substatement, call to
+ * {@link #startStatement(QName, StatementSourceReference)} needs to be done
+ * for substatement.
+ *
+ * @param name
+ * Fully qualified name of statement.
+ * @param ref
+ * Identifier of location in source, which will be used for
+ * reporting in case of statement processing error.
+ * @throws SourceException
+ * if statement is not valid according to current context.
+ */
+ void startStatement(@Nonnull QName name, @Nonnull StatementSourceReference ref) throws SourceException;
+
+ /**
+ *
+ * Emits an argument to current opened statement.
+ *
+ * <p>
+ * If statement has an argument, this must be called right after
+ * {@link #startStatement(QName, StatementSourceReference)} otherwise any
+ * subsequent call to this {@link StatementWriter} will throw
+ * {@link SourceException}.
+ *
+ *
+ *
+ * @param value
+ * String representation of value as appeared in source
+ * @param ref
+ * Identifier of location in source, which will be used for
+ * reporting in case of statement processing error.
+ * @throws SourceException
+ * if argument is not valid for current statement.
+ */
+ void argumentValue(@Nonnull String value,@Nonnull StatementSourceReference ref) throws SourceException;
+
+ /**
+ * Ends current opened statement.
+ *
+ * @param ref
+ * Identifier of location in source, which will be used for
+ * reporting in case of statement processing error.
+ * @throws SourceException
+ * if closed statement is not valid in current context, or there
+ * is no such statement
+ */
+ void endStatement(@Nonnull StatementSourceReference ref) throws SourceException;
+
+}
import com.google.common.annotations.Beta;
import com.google.common.base.Charsets;
-import com.google.common.io.CharStreams;
-import com.google.common.io.InputSupplier;
+import com.google.common.io.ByteSource;
import com.google.common.util.concurrent.CheckedFuture;
import com.google.common.util.concurrent.Futures;
LOG.debug("Model {} validated successfully", input);
// Backwards compatibility
- final String text = CharStreams.toString(
- CharStreams.newReaderSupplier(new InputSupplier<InputStream>() {
- @Override
- public InputStream getInput() throws IOException {
- return input.openStream();
- }
- }, Charsets.UTF_8));
+ final String text = new ByteSource() {
+ @Override
+ public InputStream openStream() throws IOException {
+ return input.openStream();
+ }
+ }.asCharSource(Charsets.UTF_8).read();
return Futures.immediateCheckedFuture(ASTSchemaSource.create(input.getIdentifier().getName(), ctx, text));
}
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
+import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
+
import java.io.File;
import java.io.IOException;
import java.net.URI;
assertEquals(gy.getDataChildByName("leaf-grouping-Y"),SchemaNodeUtils.getRootOriginalIfPossible( gx.getDataChildByName("leaf-grouping-Y")));
}
+ @Test
+ public void testAddedByUsesLeafTypeQName() throws IOException,
+ URISyntaxException {
+
+ Set<Module> loadModules = TestUtils.loadModules(getClass().getResource(
+ "/added-by-uses-leaf-test").toURI());
+
+ assertEquals(2, loadModules.size());
+
+ Module foo = null;
+ Module imp = null;
+ for (Module module : loadModules) {
+ if (module.getName().equals("foo")) {
+ foo = module;
+ }
+ if (module.getName().equals("import-module")) {
+ imp = module;
+ }
+ }
+
+ LeafSchemaNode leaf = (LeafSchemaNode) ((ContainerSchemaNode) foo
+ .getDataChildByName("my-container"))
+ .getDataChildByName("my-leaf");
+
+ TypeDefinition impType = null;
+ Set<TypeDefinition<?>> typeDefinitions = imp.getTypeDefinitions();
+ for (TypeDefinition<?> typeDefinition : typeDefinitions) {
+ if (typeDefinition.getQName().getLocalName().equals("imp-type")) {
+ impType = typeDefinition;
+ break;
+ }
+ }
+
+ assertEquals(leaf.getType().getQName(), impType.getQName());
+
+ }
+
}
import static org.junit.Assert.assertEquals;
import com.google.common.io.ByteSource;
import com.google.common.io.ByteStreams;
+import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
final byte[] streamContent = ByteStreams.toByteArray(stream);
- ByteSource source = ByteStreams.asByteSource(streamContent);
+ ByteSource source = new ByteSource() {
+ @Override
+ public InputStream openStream() throws IOException {
+ return new ByteArrayInputStream(streamContent);
+ }
+ };
final Collection<ByteSource> sources = Collections.singletonList(source);
SchemaContext ctx = parser.parseSources(sources, context);
import org.opendaylight.yangtools.yang.model.util.IdentityrefType;
import org.opendaylight.yangtools.yang.model.util.InstanceIdentifierType;
import org.opendaylight.yangtools.yang.model.util.UnionType;
+import org.opendaylight.yangtools.yang.parser.util.YangParseException;
public class TypesResolutionTest {
private Set<Module> testedModules;
parser.parseFiles(Arrays.asList(unionbits));
}
+ @Test(expected = YangParseException.class)
+ public void testUnionInList() throws Exception {
+ File unioninlist = new File(getClass().getResource("/types/union-in-list/unioninlisttest.yang").toURI());
+ YangContextParser parser = new YangParserImpl();
+ parser.parseFiles(Arrays.asList(unioninlist));
+ }
}
package org.opendaylight.yangtools.yang.parser.repo;
-import com.google.common.base.Objects;
+import com.google.common.base.MoreObjects;
import com.google.common.base.Preconditions;
import java.io.IOException;
import java.io.InputStream;
}
@Override
- protected Objects.ToStringHelper addToStringAttributes(final Objects.ToStringHelper toStringHelper) {
+ protected MoreObjects.ToStringHelper addToStringAttributes(final MoreObjects.ToStringHelper toStringHelper) {
return toStringHelper.add("resource", resourceName);
}
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
+import com.google.common.base.Charsets;
import com.google.common.base.Function;
-import com.google.common.base.Objects;
+import com.google.common.base.MoreObjects;
import com.google.common.base.Optional;
import com.google.common.collect.Collections2;
import com.google.common.collect.Lists;
import com.google.common.io.Files;
-import com.google.common.io.InputSupplier;
import com.google.common.util.concurrent.CheckedFuture;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
sharedSchemaRepository.registerSchemaSourceListener(listener);
final File test = new File(storageDir, "test.yang");
- Files.copy(new StringSupplier("content-test"), test);
+ Files.write("content-test", test, Charsets.UTF_8);
final File test2 = new File(storageDir, "test@2012-12-12.yang");
- Files.copy(new StringSupplier("content-test-2012"), test2);
+ Files.write("content-test-2012", test2, Charsets.UTF_8);
final File test3 = new File(storageDir, "test@2013-12-12.yang");
- Files.copy(new StringSupplier("content-test-2013"), test3);
+ Files.write("content-test-2013", test3, Charsets.UTF_8);
final File test4 = new File(storageDir, "module@2010-12-12.yang");
- Files.copy(new StringSupplier("content-module-2010"), test4);
+ Files.write("content-module-2010", test4, Charsets.UTF_8);
final FilesystemSchemaSourceCache<YangTextSchemaSource> cache = new FilesystemSchemaSourceCache<>(sharedSchemaRepository, YangTextSchemaSource.class, storageDir);
public CheckedFuture<YangTextSchemaSource, SchemaSourceException> getSource(final SourceIdentifier sourceIdentifier) {
return Futures.<YangTextSchemaSource, SchemaSourceException>immediateCheckedFuture(new YangTextSchemaSource(runningId) {
@Override
- protected Objects.ToStringHelper addToStringAttributes(final Objects.ToStringHelper toStringHelper) {
+ protected MoreObjects.ToStringHelper addToStringAttributes(final MoreObjects.ToStringHelper toStringHelper) {
return toStringHelper;
}
final CheckedFuture<ASTSchemaSource, SchemaSourceException> aSTSchemaSource = TextToASTTransformer.TRANSFORMATION.apply(yangSource);
return SettableSchemaProvider.createImmediate(aSTSchemaSource.get(), ASTSchemaSource.class);
}
-
- private class StringSupplier implements InputSupplier<InputStream> {
- private final String s;
-
- public StringSupplier(final String s) {
- this.s = s;
- }
-
- @Override
- public InputStream getInput() throws IOException {
- return IOUtils.toInputStream(s);
- }
- }
}
--- /dev/null
+module foo {
+ prefix foo;
+ namespace "namespace-foo";
+
+ import import-module { prefix imp; revision-date 1970-01-02; }
+
+ grouping grp {
+ leaf my-leaf {
+ type imp:imp-type;
+ }
+
+ }
+
+ container my-container {
+ uses grp;
+ uses imp:imp_grp;
+ }
+
+}
+
--- /dev/null
+module import-module {
+ prefix imp;
+ namespace "import-module";
+
+ revision 1970-01-02 {
+ description "Initial revision.";
+ }
+
+ typedef imp-type {
+ type string {
+ length "0..100";
+ }
+ }
+
+ grouping imp_grp {
+
+ typedef grp-type {
+ type string {
+ length "20..30";
+ }
+ }
+
+ leaf my-leaf2 {
+ type grp-type;
+ }
+
+ leaf union-leaf {
+ type union {
+ type int16;
+ type string;
+ }
+ }
+ }
+}
+
--- /dev/null
+module unioninlisttest {
+
+ namespace "urn:uilt";
+ prefix "uilt";
+
+ revision 2015-01-13 {
+ }
+
+ list foo {
+ key "name";
+ unique "ip port";
+
+ leaf name {
+ type string;
+ }
+
+ union {
+ type int32;
+ type enumeration {
+ enum "test";
+ }
+ }
+
+ leaf ip {
+ type string;
+ }
+
+ leaf port {
+ type string;
+ }
+ }
+}
\ No newline at end of file