import org.opendaylight.yangtools.yang.model.api.type.IntegerTypeDefinition;
import org.opendaylight.yangtools.yang.model.api.type.UnsignedIntegerTypeDefinition;
+import com.google.common.base.Preconditions;
import com.google.gson.stream.JsonWriter;
class JsonMapper {
private final Set<ListSchemaNode> foundLists = new HashSet<>();
public void write(JsonWriter writer, CompositeNode data, DataNodeContainer schema) throws IOException {
+ Preconditions.checkNotNull(writer);
+ Preconditions.checkNotNull(data);
+ Preconditions.checkNotNull(schema);
+
writer.beginObject();
if (schema instanceof ContainerSchemaNode) {
- writeContainer(writer, (CompositeNode) data, (ContainerSchemaNode) schema);
+ writeContainer(writer, data, (ContainerSchemaNode) schema);
} else if (schema instanceof ListSchemaNode) {
- writeList(writer, (CompositeNode) data, (ListSchemaNode) schema);
+ writeList(writer, data, (ListSchemaNode) schema);
} else {
throw new UnsupportedDataTypeException(
"Schema can be ContainerSchemaNode or ListSchemaNode. Other types are not supported yet.");
checkNotNull(parentSchema);
for (Node<?> child : parent.getChildren()) {
- DataSchemaNode childSchema = findSchemaForNode(child, parentSchema.getChildNodes());
+ DataSchemaNode childSchema = findFirstSchemaForNode(child, parentSchema.getChildNodes());
if (childSchema == null) {
throw new UnsupportedDataTypeException("Probably the data node \"" + child.getNodeType().getLocalName()
+ "\" is not conform to schema");
}
if (childSchema instanceof ContainerSchemaNode) {
+ Preconditions.checkState(child instanceof CompositeNode,
+ "Data representation of Container should be CompositeNode - " + child.getNodeType());
writeContainer(writer, (CompositeNode) child, (ContainerSchemaNode) childSchema);
} else if (childSchema instanceof ListSchemaNode) {
if (!foundLists.contains(childSchema)) {
+ Preconditions.checkState(child instanceof CompositeNode,
+ "Data representation of List should be CompositeNode - " + child.getNodeType());
foundLists.add((ListSchemaNode) childSchema);
writeList(writer, (CompositeNode) child, (ListSchemaNode) childSchema);
}
} else if (childSchema instanceof LeafListSchemaNode) {
if (!foundLeafLists.contains(childSchema)) {
+ Preconditions.checkState(child instanceof SimpleNode<?>,
+ "Data representation of LeafList should be SimpleNode - " + child.getNodeType());
foundLeafLists.add((LeafListSchemaNode) childSchema);
writeLeafList(writer, (SimpleNode<?>) child, (LeafListSchemaNode) childSchema);
}
} else if (childSchema instanceof LeafSchemaNode) {
+ Preconditions.checkState(child instanceof SimpleNode<?>,
+ "Data representation of LeafList should be SimpleNode - " + child.getNodeType());
writeLeaf(writer, (SimpleNode<?>) child, (LeafSchemaNode) childSchema);
} else {
throw new UnsupportedDataTypeException("Schema can be ContainerSchemaNode, ListSchemaNode, "
}
for (Node<?> child : parent.getChildren()) {
- DataSchemaNode childSchema = findSchemaForNode(child, parentSchema.getChildNodes());
+ DataSchemaNode childSchema = findFirstSchemaForNode(child, parentSchema.getChildNodes());
if (childSchema instanceof LeafListSchemaNode) {
foundLeafLists.remove((LeafListSchemaNode) childSchema);
} else if (childSchema instanceof ListSchemaNode) {
}
}
- private DataSchemaNode findSchemaForNode(Node<?> node, Set<DataSchemaNode> dataSchemaNode) {
+ private DataSchemaNode findFirstSchemaForNode(Node<?> node, Set<DataSchemaNode> dataSchemaNode) {
for (DataSchemaNode dsn : dataSchemaNode) {
if (node.getNodeType().getLocalName().equals(dsn.getQName().getLocalName())) {
return dsn;
writer.nullValue();
writer.endArray();
} else {
- writer.value(value);
+ writer.value(value != null ? value : "");
}
}
--- /dev/null
+package org.opendaylight.controller.sal.rest.impl;
+
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import org.opendaylight.controller.sal.restconf.impl.CompositeNodeWrapper;
+import org.opendaylight.controller.sal.restconf.impl.SimpleNodeWrapper;
+
+import com.google.common.collect.Lists;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import com.google.gson.JsonPrimitive;
+
+class JsonReader {
+
+ public CompositeNodeWrapper read(InputStream entityStream) throws UnsupportedJsonFormatException {
+ JsonParser parser = new JsonParser();
+
+ JsonElement rootElement = parser.parse(new InputStreamReader(entityStream));
+ if (!rootElement.isJsonObject()) {
+ throw new UnsupportedJsonFormatException("Root element of Json has to be Object");
+ }
+
+ Set<Entry<String, JsonElement>> entrySetsOfRootJsonObject = rootElement.getAsJsonObject().entrySet();
+ if (entrySetsOfRootJsonObject.size() != 1) {
+ throw new UnsupportedJsonFormatException("Json Object should contain one element");
+ } else {
+ Entry<String, JsonElement> childEntry = Lists.newArrayList(entrySetsOfRootJsonObject).get(0);
+ String firstElementName = childEntry.getKey();
+ JsonElement firstElementType = childEntry.getValue();
+ if (firstElementType.isJsonObject()) { // container in yang
+ return createStructureWithRoot(firstElementName, firstElementType.getAsJsonObject());
+ }
+ if (firstElementType.isJsonArray()) { // list in yang
+ if (firstElementType.getAsJsonArray().size() == 1) {
+ JsonElement firstElementInArray = firstElementType.getAsJsonArray().get(0);
+ if (firstElementInArray.isJsonObject()) {
+ return createStructureWithRoot(firstElementName, firstElementInArray.getAsJsonObject());
+ }
+ throw new UnsupportedJsonFormatException("Array as the first element in Json Object can have only Object element");
+ }
+ }
+ throw new UnsupportedJsonFormatException("First element in Json Object has to be \"Object\" or \"Array with one Object element\". Other scenarios are not supported yet.");
+ }
+ }
+
+ private CompositeNodeWrapper createStructureWithRoot(String rootObjectName, JsonObject rootObject) {
+ CompositeNodeWrapper firstNode = new CompositeNodeWrapper(rootObjectName);
+ for (Entry<String, JsonElement> childOfFirstNode : rootObject.entrySet()) {
+ addChildToParent(childOfFirstNode.getKey(), childOfFirstNode.getValue(), firstNode);
+ }
+ return firstNode;
+ }
+
+ private void addChildToParent(String childName, JsonElement childType, CompositeNodeWrapper parent) {
+ if (childType.isJsonObject()) {
+ CompositeNodeWrapper child = new CompositeNodeWrapper(childName);
+ parent.addValue(child);
+ for (Entry<String, JsonElement> childOfChild : childType.getAsJsonObject().entrySet()) {
+ addChildToParent(childOfChild.getKey(), childOfChild.getValue(), child);
+ }
+ } else if (childType.isJsonArray()) {
+ for (JsonElement childOfChildType : childType.getAsJsonArray()) {
+ addChildToParent(childName, childOfChildType, parent);
+ }
+ } else if (childType.isJsonPrimitive()) {
+ JsonPrimitive childPrimitive = childType.getAsJsonPrimitive();
+ String value = childPrimitive.getAsString();
+ SimpleNodeWrapper child = null;
+ if (value.equals("[null]")) {
+ child = new SimpleNodeWrapper(childName, null);
+ } else {
+ child = new SimpleNodeWrapper(childName, value);
+ }
+ parent.addValue(child);
+ }
+ }
+}
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.Response;
import javax.ws.rs.ext.MessageBodyReader;
import javax.ws.rs.ext.Provider;
@Consumes({API+RestconfService.JSON})
public enum JsonToCompositeNodeProvider implements MessageBodyReader<CompositeNode> {
INSTANCE;
-
+
@Override
public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
return true;
public CompositeNode readFrom(Class<CompositeNode> type, Type genericType, Annotation[] annotations,
MediaType mediaType, MultivaluedMap<String, String> httpHeaders, InputStream entityStream)
throws IOException, WebApplicationException {
- // TODO Auto-generated method stub
- return null;
+ JsonReader jsonReader = new JsonReader();
+ try {
+ return jsonReader.read(entityStream);
+ } catch (UnsupportedJsonFormatException e) {
+ throw new WebApplicationException(Response.status(Response.Status.BAD_REQUEST)
+ .entity(e.getMessage()).build());
+ }
}
}
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.Response;
import javax.ws.rs.ext.MessageBodyWriter;
import javax.ws.rs.ext.Provider;
import org.opendaylight.controller.sal.rest.api.RestconfService;
import org.opendaylight.controller.sal.restconf.impl.StructuredData;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
import com.google.gson.stream.JsonWriter;
public void writeTo(StructuredData t, Class<?> type, Type genericType, Annotation[] annotations,
MediaType mediaType, MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream)
throws IOException, WebApplicationException {
+ CompositeNode data = t.getData();
+ if (data == null) {
+ throw new WebApplicationException(Response.status(Response.Status.NOT_FOUND).build());
+ }
+
JsonWriter writer = new JsonWriter(new OutputStreamWriter(entityStream, "UTF-8"));
writer.setIndent(" ");
JsonMapper jsonMapper = new JsonMapper();
- jsonMapper.write(writer, t.getData(), (DataNodeContainer) t.getSchema());
+ jsonMapper.write(writer, data, (DataNodeContainer) t.getSchema());
writer.flush();
}
-
+
}
MediaType mediaType, MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream)
throws IOException, WebApplicationException {
CompositeNode data = t.getData();
- Document domTree = NodeUtils.buildShadowDomTree(data);
+ if (data == null) {
+ throw new WebApplicationException(Response.status(Response.Status.NOT_FOUND).build());
+ }
+ Document domTree = NodeUtils.buildShadowDomTree(data);
try {
TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = tf.newTransformer();
transformer.transform(new DOMSource(domTree), new StreamResult(entityStream));
} catch (TransformerException e) {
logger.error("Error during translation of Document to OutputStream", e);
- new WebApplicationException(Response.status(Response.Status.INTERNAL_SERVER_ERROR).build());
+ throw new WebApplicationException(Response.status(Response.Status.INTERNAL_SERVER_ERROR).build());
}
}
--- /dev/null
+package org.opendaylight.controller.sal.rest.impl;
+
+public class UnsupportedJsonFormatException extends Exception {
+
+ private static final long serialVersionUID = -1741388894406313402L;
+
+ public UnsupportedJsonFormatException() {
+ super();
+ }
+
+ public UnsupportedJsonFormatException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public UnsupportedJsonFormatException(String message) {
+ super(message);
+ }
+
+ public UnsupportedJsonFormatException(Throwable cause) {
+ super(cause);
+ }
+
+}
--- /dev/null
+package org.opendaylight.controller.sal.restconf.impl;
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.ModifyAction;
+import org.opendaylight.yangtools.yang.data.api.MutableCompositeNode;
+import org.opendaylight.yangtools.yang.data.api.Node;
+import org.opendaylight.yangtools.yang.data.api.SimpleNode;
+import org.opendaylight.yangtools.yang.data.impl.NodeFactory;
+
+import com.google.common.base.Preconditions;
+
+public final class CompositeNodeWrapper implements NodeWrapper<CompositeNode>, CompositeNode {
+
+ private MutableCompositeNode compositeNode;
+
+ private String localName;
+ private URI namespace;
+ private List<NodeWrapper<?>> values = new ArrayList<>();
+
+ public CompositeNodeWrapper(String localName) {
+ this.localName = Preconditions.checkNotNull(localName);
+ }
+
+ @Override
+ public String getLocalName() {
+ if (compositeNode != null) {
+ return compositeNode.getNodeType().getLocalName();
+ }
+ return localName;
+ }
+
+ @Override
+ public URI getNamespace() {
+ if (compositeNode != null) {
+ return compositeNode.getNodeType().getNamespace();
+ }
+ return namespace;
+ }
+
+ @Override
+ public void setNamespace(URI namespace) {
+ Preconditions.checkState(compositeNode == null, "Cannot change the object, due to data inconsistencies.");
+ this.namespace = namespace;
+ }
+
+ public void addValue(NodeWrapper<?> value) {
+ Preconditions.checkState(compositeNode == null, "Cannot change the object, due to data inconsistencies.");
+ values.add(value);
+ }
+
+ public void removeValue(NodeWrapper<CompositeNode> value) {
+ Preconditions.checkState(compositeNode == null, "Cannot change the object, due to data inconsistencies.");
+ values.remove(value);
+ }
+
+ public List<NodeWrapper<?>> getValues() {
+ Preconditions.checkState(compositeNode == null, "Data can be inconsistent.");
+ return Collections.unmodifiableList(values);
+ }
+
+ @Override
+ public CompositeNode unwrap(CompositeNode parent) {
+ if (compositeNode == null) {
+ Preconditions.checkNotNull(namespace);
+ compositeNode = NodeFactory.createMutableCompositeNode(new QName(namespace, localName),
+ parent, new ArrayList<Node<?>>(), ModifyAction.CREATE, null);
+
+ List<Node<?>> nodeValues = new ArrayList<>();
+ for (NodeWrapper<?> nodeWrapper : values) {
+ nodeValues.add(nodeWrapper.unwrap(compositeNode));
+ }
+ compositeNode.setValue(nodeValues);
+
+ values = null;
+ namespace = null;
+ localName = null;
+ }
+ return compositeNode;
+ }
+
+ @Override
+ public QName getNodeType() {
+ return unwrap(null).getNodeType();
+ }
+
+ @Override
+ public CompositeNode getParent() {
+ return unwrap(null).getParent();
+ }
+
+ @Override
+ public List<Node<?>> getValue() {
+ return unwrap(null).getValue();
+ }
+
+ @Override
+ public ModifyAction getModificationAction() {
+ return unwrap(null).getModificationAction();
+ }
+
+ @Override
+ public List<Node<?>> getChildren() {
+ return unwrap(null).getChildren();
+ }
+
+ @Override
+ public List<CompositeNode> getCompositesByName(QName children) {
+ return unwrap(null).getCompositesByName(children);
+ }
+
+ @Override
+ public List<CompositeNode> getCompositesByName(String children) {
+ return unwrap(null).getCompositesByName(children);
+ }
+
+ @Override
+ public List<SimpleNode<?>> getSimpleNodesByName(QName children) {
+ return unwrap(null).getSimpleNodesByName(children);
+ }
+
+ @Override
+ public List<SimpleNode<?>> getSimpleNodesByName(String children) {
+ return unwrap(null).getSimpleNodesByName(children);
+ }
+
+ @Override
+ public CompositeNode getFirstCompositeByName(QName container) {
+ return unwrap(null).getFirstCompositeByName(container);
+ }
+
+ @Override
+ public SimpleNode<?> getFirstSimpleByName(QName leaf) {
+ return unwrap(null).getFirstSimpleByName(leaf);
+ }
+
+ @Override
+ public MutableCompositeNode asMutable() {
+ return unwrap(null).asMutable();
+ }
+
+ @Override
+ public QName getKey() {
+ return unwrap(null).getKey();
+ }
+
+ @Override
+ public List<Node<?>> setValue(List<Node<?>> value) {
+ return unwrap(null).setValue(value);
+ }
+
+ @Override
+ public int size() {
+ return unwrap(null).size();
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return unwrap(null).isEmpty();
+ }
+
+ @Override
+ public boolean containsKey(Object key) {
+ return unwrap(null).containsKey(key);
+ }
+
+ @Override
+ public boolean containsValue(Object value) {
+ return unwrap(null).containsValue(value);
+ }
+
+ @Override
+ public List<Node<?>> get(Object key) {
+ return unwrap(null).get(key);
+ }
+
+ @Override
+ public List<Node<?>> put(QName key, List<Node<?>> value) {
+ return unwrap(null).put(key, value);
+ }
+
+ @Override
+ public List<Node<?>> remove(Object key) {
+ return unwrap(null).remove(key);
+ }
+
+ @Override
+ public void putAll(Map<? extends QName, ? extends List<Node<?>>> m) {
+ unwrap(null).putAll(m);
+ }
+
+ @Override
+ public void clear() {
+ unwrap(null).clear();
+ }
+
+ @Override
+ public Set<QName> keySet() {
+ return unwrap(null).keySet();
+ }
+
+ @Override
+ public Collection<List<Node<?>>> values() {
+ return unwrap(null).values();
+ }
+
+ @Override
+ public Set<java.util.Map.Entry<QName, List<Node<?>>>> entrySet() {
+ return unwrap(null).entrySet();
+ }
+
+}
def ContainerSchemaNode getRpcOutputSchema(QName name) {
qnameToRpc.get(name)?.output;
}
+
+ def ContainerSchemaNode getRpcInputSchema(QName name) {
+ qnameToRpc.get(name)?.input;
+ }
}
--- /dev/null
+package org.opendaylight.controller.sal.restconf.impl;
+
+import java.net.URI;
+
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.Node;
+
+public interface NodeWrapper<T extends Node<?>> {
+
+ T unwrap(CompositeNode parent);
+
+ URI getNamespace();
+
+ void setNamespace(URI namespace);
+
+ String getLocalName();
+}
\ No newline at end of file
package org.opendaylight.controller.sal.restconf.impl
-import org.opendaylight.yangtools.yang.data.api.CompositeNode
+import java.util.List
import org.opendaylight.controller.sal.rest.api.RestconfService
+import org.opendaylight.yangtools.yang.data.api.CompositeNode
+import org.opendaylight.yangtools.yang.model.api.DataNodeContainer
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode
class RestconfImpl implements RestconfService {
override createConfigurationData(String identifier, CompositeNode payload) {
val identifierWithSchemaNode = identifier.toInstanceIdentifier
- return broker.commitConfigurationDataPut(identifierWithSchemaNode.instanceIdentifier,payload).get();
+ val value = resolveNodeNamespaceBySchema(payload, identifierWithSchemaNode.schemaNode)
+ return broker.commitConfigurationDataPut(identifierWithSchemaNode.instanceIdentifier,value).get();
}
override updateConfigurationData(String identifier, CompositeNode payload) {
val identifierWithSchemaNode = identifier.toInstanceIdentifier
- return broker.commitConfigurationDataPut(identifierWithSchemaNode.instanceIdentifier,payload).get();
+ val value = resolveNodeNamespaceBySchema(payload, identifierWithSchemaNode.schemaNode)
+ return broker.commitConfigurationDataPut(identifierWithSchemaNode.instanceIdentifier,value).get();
}
override invokeRpc(String identifier, CompositeNode payload) {
val rpc = identifier.toQName;
- val rpcResult = broker.invokeRpc(rpc, payload);
+ val value = resolveNodeNamespaceBySchema(payload, controllerContext.getRpcInputSchema(rpc))
+ val rpcResult = broker.invokeRpc(rpc, value);
val schema = controllerContext.getRpcOutputSchema(rpc);
return new StructuredData(rpcResult.result, schema);
}
override createOperationalData(String identifier, CompositeNode payload) {
val identifierWithSchemaNode = identifier.toInstanceIdentifier
- return broker.commitOperationalDataPut(identifierWithSchemaNode.instanceIdentifier,payload).get();
+ val value = resolveNodeNamespaceBySchema(payload, identifierWithSchemaNode.schemaNode)
+ return broker.commitOperationalDataPut(identifierWithSchemaNode.instanceIdentifier,value).get();
}
override updateOperationalData(String identifier, CompositeNode payload) {
val identifierWithSchemaNode = identifier.toInstanceIdentifier
- return broker.commitOperationalDataPut(identifierWithSchemaNode.instanceIdentifier,payload).get();
+ val value = resolveNodeNamespaceBySchema(payload, identifierWithSchemaNode.schemaNode)
+ return broker.commitOperationalDataPut(identifierWithSchemaNode.instanceIdentifier,value).get();
+ }
+
+ private def CompositeNode resolveNodeNamespaceBySchema(CompositeNode node, DataSchemaNode schema) {
+ if (node instanceof CompositeNodeWrapper) {
+ addNamespaceToNodeFromSchemaRecursively(node as CompositeNodeWrapper, schema)
+ return (node as CompositeNodeWrapper).unwrap(null)
+ }
+ return node
+ }
+
+ private def void addNamespaceToNodeFromSchemaRecursively(NodeWrapper<?> nodeBuilder, DataSchemaNode schema) {
+ if (nodeBuilder.namespace == null) {
+ nodeBuilder.namespace = schema.QName.namespace
+ }
+ if (nodeBuilder instanceof CompositeNodeWrapper) {
+ val List<NodeWrapper<?>> children = (nodeBuilder as CompositeNodeWrapper).getValues
+ for (child : children) {
+ addNamespaceToNodeFromSchemaRecursively(child,
+ (schema as DataNodeContainer).childNodes.findFirst[n|n.QName.localName === child.localName])
+ }
+ }
}
}
--- /dev/null
+package org.opendaylight.controller.sal.restconf.impl;
+
+import java.net.URI;
+
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.ModifyAction;
+import org.opendaylight.yangtools.yang.data.api.MutableSimpleNode;
+import org.opendaylight.yangtools.yang.data.api.SimpleNode;
+import org.opendaylight.yangtools.yang.data.impl.NodeFactory;
+
+import com.google.common.base.Preconditions;
+
+public final class SimpleNodeWrapper implements NodeWrapper<SimpleNode<?>>, SimpleNode<String> {
+
+ private SimpleNode<String> simpleNode;
+
+ private String localName;
+ private String value;
+ private URI namespace;
+
+ public SimpleNodeWrapper(String localName, String value) {
+ this.localName = Preconditions.checkNotNull(localName);
+ this.value = value;
+ }
+
+ @Override
+ public String getLocalName() {
+ if (simpleNode != null) {
+ return simpleNode.getNodeType().getLocalName();
+ }
+ return localName;
+ }
+
+ @Override
+ public URI getNamespace() {
+ if (simpleNode != null) {
+ return simpleNode.getNodeType().getNamespace();
+ }
+ return namespace;
+ }
+
+ @Override
+ public void setNamespace(URI namespace) {
+ Preconditions.checkState(simpleNode == null, "Cannot change the object, due to data inconsistencies.");
+ this.namespace = namespace;
+ }
+
+ @Override
+ public SimpleNode<String> unwrap(CompositeNode parent) {
+ if (simpleNode == null) {
+ Preconditions.checkNotNull(namespace);
+ simpleNode = NodeFactory.createImmutableSimpleNode(new QName(namespace, localName), parent, value);
+
+ value = null;
+ namespace = null;
+ localName = null;
+ }
+ return simpleNode;
+ }
+
+ @Override
+ public QName getNodeType() {
+ return unwrap(null).getNodeType();
+ }
+
+ @Override
+ public CompositeNode getParent() {
+ return unwrap(null).getParent();
+ }
+
+ @Override
+ public String getValue() {
+ return unwrap(null).getValue();
+ }
+
+ @Override
+ public ModifyAction getModificationAction() {
+ return unwrap(null).getModificationAction();
+ }
+
+ @Override
+ public MutableSimpleNode<String> asMutable() {
+ return unwrap(null).asMutable();
+ }
+
+ @Override
+ public QName getKey() {
+ return unwrap(null).getKey();
+ }
+
+ @Override
+ public String setValue(String value) {
+ return unwrap(null).setValue(value);
+ }
+
+
+}