Fix NPE when trying to download restconf provided yang files
[netconf.git] / restconf / restconf-nb-bierman02 / src / main / java / org / opendaylight / netconf / md / sal / rest / schema / SchemaRetrievalServiceImpl.java
1 /*
2  * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.netconf.md.sal.rest.schema;
9
10 import com.google.common.base.Splitter;
11 import com.google.common.collect.Iterables;
12 import java.text.ParseException;
13 import java.util.Date;
14 import java.util.Iterator;
15 import org.opendaylight.mdsal.dom.api.DOMYangTextSourceProvider;
16 import org.opendaylight.netconf.sal.restconf.impl.ControllerContext;
17 import org.opendaylight.restconf.common.context.InstanceIdentifierContext;
18 import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
19 import org.opendaylight.restconf.common.errors.RestconfError.ErrorTag;
20 import org.opendaylight.restconf.common.errors.RestconfError.ErrorType;
21 import org.opendaylight.restconf.common.schema.SchemaExportContext;
22 import org.opendaylight.restconf.common.validation.RestconfValidationUtils;
23 import org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil;
24 import org.opendaylight.yangtools.yang.model.api.Module;
25 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
26
27 public class SchemaRetrievalServiceImpl implements SchemaRetrievalService {
28
29     private final ControllerContext salContext;
30
31     private static final Splitter SLASH_SPLITTER = Splitter.on("/");
32     private static final String MOUNT_ARG = ControllerContext.MOUNT;
33
34     public SchemaRetrievalServiceImpl(final ControllerContext controllerContext) {
35         salContext = controllerContext;
36     }
37
38
39     @Override
40     public SchemaExportContext getSchema(final String mountAndModule) {
41         final SchemaContext schemaContext;
42         final Iterable<String> pathComponents = SLASH_SPLITTER.split(mountAndModule);
43         final Iterator<String> componentIter = pathComponents.iterator();
44         if (!Iterables.contains(pathComponents, MOUNT_ARG)) {
45             schemaContext = salContext.getGlobalSchema();
46         } else {
47             final StringBuilder pathBuilder = new StringBuilder();
48             while (componentIter.hasNext()) {
49                 final String current = componentIter.next();
50                 // It is argument, not last element.
51                 if (pathBuilder.length() != 0) {
52                     pathBuilder.append("/");
53                 }
54                 pathBuilder.append(current);
55                 if (MOUNT_ARG.equals(current)) {
56                     // We stop right at mountpoint, last two arguments should
57                     // be module name and revision
58                     break;
59                 }
60             }
61             schemaContext = getMountSchemaContext(pathBuilder.toString());
62
63         }
64
65         RestconfValidationUtils.checkDocumentedError(componentIter.hasNext(),
66                 ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE, "Module name must be supplied.");
67         final String moduleName = componentIter.next();
68         RestconfValidationUtils.checkDocumentedError(componentIter.hasNext(),
69                 ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE, "Revision date must be supplied.");
70         final String revisionString = componentIter.next();
71         return getExportUsingNameAndRevision(schemaContext, moduleName, revisionString,
72                 salContext.getYangTextSourceProvider());
73     }
74
75     private static SchemaExportContext getExportUsingNameAndRevision(final SchemaContext schemaContext,
76              final String moduleName, final String revisionStr,
77              final DOMYangTextSourceProvider yangTextSourceProvider) {
78         try {
79             final Date revision = SimpleDateFormatUtil.getRevisionFormat().parse(revisionStr);
80             final Module module = schemaContext.findModuleByName(moduleName, revision);
81
82             return new SchemaExportContext(
83                     schemaContext, RestconfValidationUtils.checkNotNullDocumented(module, moduleName),
84                     yangTextSourceProvider);
85         } catch (final ParseException e) {
86             throw new RestconfDocumentedException("Supplied revision is not in expected date format YYYY-mm-dd", e);
87         }
88     }
89
90     private SchemaContext getMountSchemaContext(final String identifier) {
91         final InstanceIdentifierContext<?> mountContext = salContext.toMountPointIdentifier(identifier);
92         return mountContext.getSchemaContext();
93     }
94 }
95