2 * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.controller.md.sal.rest.common;
11 import com.google.common.base.Preconditions;
13 import java.io.FileNotFoundException;
14 import java.io.IOException;
15 import java.io.InputStream;
16 import java.util.ArrayList;
17 import java.util.Collection;
18 import java.util.Collections;
19 import java.util.List;
20 import javax.xml.parsers.DocumentBuilder;
21 import javax.xml.parsers.DocumentBuilderFactory;
22 import javax.xml.parsers.ParserConfigurationException;
23 import org.opendaylight.controller.sal.rest.impl.test.providers.TestJsonBodyWriter;
24 import org.opendaylight.controller.sal.restconf.impl.ControllerContext;
25 import org.opendaylight.controller.sal.restconf.impl.InstanceIdentifierContext;
26 import org.opendaylight.controller.sal.restconf.impl.NormalizedNodeContext;
27 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
28 import org.opendaylight.yangtools.yang.data.impl.codec.xml.XmlUtils;
29 import org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.parser.DomToNormalizedNodeParserFactory;
30 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
31 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
32 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
33 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
34 import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
35 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
36 import org.opendaylight.yangtools.yang.model.api.SchemaNode;
37 import org.opendaylight.yangtools.yang.model.parser.api.YangContextParser;
38 import org.opendaylight.yangtools.yang.model.parser.api.YangSyntaxErrorException;
39 import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
40 import org.slf4j.Logger;
41 import org.slf4j.LoggerFactory;
42 import org.w3c.dom.Document;
43 import org.w3c.dom.Element;
47 * org.opendaylight.controller.md.sal.rest.common
51 * @author <a href="mailto:vdemcak@cisco.com">Vaclav Demcak</a>
53 * Created: Mar 7, 2015
55 public class TestRestconfUtils {
57 private static final Logger LOG = LoggerFactory.getLogger(TestRestconfUtils.class);
59 private static final YangContextParser parser = new YangParserImpl();
61 private static final DocumentBuilderFactory BUILDERFACTORY;
64 final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
66 factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
67 factory.setFeature("http://xml.org/sax/features/external-general-entities", false);
68 factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
69 factory.setXIncludeAware(false);
70 factory.setExpandEntityReferences(false);
71 } catch (final ParserConfigurationException e) {
72 throw new ExceptionInInitializerError(e);
74 factory.setNamespaceAware(true);
75 factory.setCoalescing(true);
76 factory.setIgnoringElementContentWhitespace(true);
77 factory.setIgnoringComments(true);
78 BUILDERFACTORY = factory;
81 private TestRestconfUtils () {
82 throw new UnsupportedOperationException("Test utility class");
85 public static SchemaContext loadSchemaContext(final String yangPath, final SchemaContext schemaContext) {
87 Preconditions.checkArgument(yangPath != null, "Path can not be null.");
88 Preconditions.checkArgument(( ! yangPath.isEmpty()), "Path can not be empty.");
89 if (schemaContext == null) {
90 return loadSchemaContext(yangPath);
92 return addSchemaContext(yangPath, schemaContext);
95 catch (final Exception e) {
96 LOG.error("Yang files at path: " + yangPath + " weren't loaded.");
101 public static NormalizedNodeContext loadNormalizedContextFromJsonFile() {
102 throw new AbstractMethodError("Not implemented yet");
105 public static NormalizedNodeContext loadNormalizedContextFromXmlFile(final String pathToInputFile, final String uri) {
106 final InstanceIdentifierContext<?> iiContext = ControllerContext.getInstance().toInstanceIdentifier(uri);
107 final InputStream inputStream = TestJsonBodyWriter.class.getResourceAsStream(pathToInputFile);
109 final DocumentBuilder dBuilder = BUILDERFACTORY.newDocumentBuilder();
110 final Document doc = dBuilder.parse(inputStream);
111 final NormalizedNode<?, ?> nn = parse(iiContext, doc);
112 return new NormalizedNodeContext(iiContext, nn);
114 catch (final Exception e) {
115 LOG.error("Load xml file " + pathToInputFile + " fail.", e);
120 private static NormalizedNode<?, ?> parse(final InstanceIdentifierContext<?> iiContext, final Document doc) {
121 final List<Element> elements = Collections.singletonList(doc.getDocumentElement());
122 final SchemaNode schemaNodeContext = iiContext.getSchemaNode();
123 DataSchemaNode schemaNode = null;
124 if (schemaNodeContext instanceof RpcDefinition) {
125 if ("input".equalsIgnoreCase(doc.getDocumentElement().getLocalName())) {
126 schemaNode = ((RpcDefinition) schemaNodeContext).getInput();
127 } else if ("output".equalsIgnoreCase(doc.getDocumentElement().getLocalName())) {
128 schemaNode = ((RpcDefinition) schemaNodeContext).getOutput();
130 throw new IllegalStateException("Unknown Rpc input node");
133 } else if (schemaNodeContext instanceof DataSchemaNode) {
134 schemaNode = (DataSchemaNode) schemaNodeContext;
136 throw new IllegalStateException("Unknow SchemaNode");
139 final String docRootElm = doc.getDocumentElement().getLocalName();
140 final String schemaNodeName = iiContext.getSchemaNode().getQName().getLocalName();
142 if (!schemaNodeName.equalsIgnoreCase(docRootElm)) {
143 final Collection<DataSchemaNode> children = ((DataNodeContainer) schemaNode).getChildNodes();
144 for (final DataSchemaNode child : children) {
145 if (child.getQName().getLocalName().equalsIgnoreCase(docRootElm)) {
151 final DomToNormalizedNodeParserFactory parserFactory =
152 DomToNormalizedNodeParserFactory.getInstance(XmlUtils.DEFAULT_XML_CODEC_PROVIDER, iiContext.getSchemaContext());
154 if(schemaNode instanceof ContainerSchemaNode) {
155 return parserFactory.getContainerNodeParser().parse(Collections.singletonList(doc.getDocumentElement()), (ContainerSchemaNode) schemaNode);
156 } else if(schemaNode instanceof ListSchemaNode) {
157 final ListSchemaNode casted = (ListSchemaNode) schemaNode;
158 return parserFactory.getMapEntryNodeParser().parse(elements, casted);
159 } // FIXME : add another DataSchemaNode extensions e.g. LeafSchemaNode
163 private static Collection<File> loadFiles(final String resourceDirectory) throws FileNotFoundException {
164 final String path = TestRestconfUtils.class.getResource(resourceDirectory).getPath();
165 final File testDir = new File(path);
166 final String[] fileList = testDir.list();
167 final List<File> testFiles = new ArrayList<File>();
168 if (fileList == null) {
169 throw new FileNotFoundException(resourceDirectory);
171 for (int i = 0; i < fileList.length; i++) {
172 final String fileName = fileList[i];
173 if (new File(testDir, fileName).isDirectory() == false) {
174 testFiles.add(new File(testDir, fileName));
180 private static SchemaContext loadSchemaContext(final String resourceDirectory) throws IOException {
181 final Collection<File> testFiles = loadFiles(resourceDirectory);
182 return parser.parseFiles(testFiles);
185 private static SchemaContext addSchemaContext(final String resourceDirectory,
186 final SchemaContext schemaContext) throws IOException, YangSyntaxErrorException {
187 final Collection<File> testFiles = loadFiles(resourceDirectory);
188 return parser.parseFiles(testFiles, schemaContext);