+ /**
+ * Go through uses statements defined in current module and resolve their
+ * refine statements.
+ *
+ * @param modules
+ * all modules
+ * @param module
+ * module being resolved
+ */
+ private void resolveUses(
+ final Map<String, TreeMap<Date, ModuleBuilder>> modules,
+ final ModuleBuilder module) {
+ final Map<List<String>, UsesNodeBuilder> moduleUses = module
+ .getAddedUsesNodes();
+ for (Map.Entry<List<String>, UsesNodeBuilder> entry : moduleUses
+ .entrySet()) {
+ final List<String> key = entry.getKey();
+ final UsesNodeBuilder usesNode = entry.getValue();
+
+ final String groupingName = key.get(key.size() - 1);
+
+ for (RefineHolder refine : usesNode.getRefines()) {
+ // refine statements
+ final String defaultStr = refine.getDefaultStr();
+ final Boolean mandatory = refine.isMandatory();
+ final MustDefinition must = refine.getMust();
+ final Boolean presence = refine.isPresence();
+ final Integer min = refine.getMinElements();
+ final Integer max = refine.getMaxElements();
+ final List<UnknownSchemaNodeBuilder> unknownNodes = refine
+ .getUnknownNodes();
+
+ Builder refineTarget = getRefineTargetBuilder(groupingName,
+ refine, modules, module);
+ if (refineTarget instanceof LeafSchemaNodeBuilder) {
+ final LeafSchemaNodeBuilder leaf = (LeafSchemaNodeBuilder) refineTarget;
+ if (defaultStr != null && !("".equals(defaultStr))) {
+ leaf.setDefaultStr(defaultStr);
+ }
+ if (mandatory != null) {
+ leaf.getConstraints().setMandatory(mandatory);
+ }
+ if (must != null) {
+ leaf.getConstraints().addMustDefinition(must);
+ }
+ if (unknownNodes != null) {
+ for (UnknownSchemaNodeBuilder unknown : unknownNodes) {
+ leaf.addUnknownSchemaNode(unknown);
+ }
+ }
+ usesNode.addRefineNode(leaf);
+ } else if (refineTarget instanceof ContainerSchemaNodeBuilder) {
+ final ContainerSchemaNodeBuilder container = (ContainerSchemaNodeBuilder) refineTarget;
+ if (presence != null) {
+ container.setPresence(presence);
+ }
+ if (must != null) {
+ container.getConstraints().addMustDefinition(must);
+ }
+ if (unknownNodes != null) {
+ for (UnknownSchemaNodeBuilder unknown : unknownNodes) {
+ container.addUnknownSchemaNode(unknown);
+ }
+ }
+ usesNode.addRefineNode(container);
+ } else if (refineTarget instanceof ListSchemaNodeBuilder) {
+ final ListSchemaNodeBuilder list = (ListSchemaNodeBuilder) refineTarget;
+ if (must != null) {
+ list.getConstraints().addMustDefinition(must);
+ }
+ if (min != null) {
+ list.getConstraints().setMinElements(min);
+ }
+ if (max != null) {
+ list.getConstraints().setMaxElements(max);
+ }
+ if (unknownNodes != null) {
+ for (UnknownSchemaNodeBuilder unknown : unknownNodes) {
+ list.addUnknownSchemaNode(unknown);
+ }
+ }
+ } else if (refineTarget instanceof LeafListSchemaNodeBuilder) {
+ final LeafListSchemaNodeBuilder leafList = (LeafListSchemaNodeBuilder) getRefineTargetBuilder(
+ groupingName, refine, modules, module);
+ if (must != null) {
+ leafList.getConstraints().addMustDefinition(must);
+ }
+ if (min != null) {
+ leafList.getConstraints().setMinElements(min);
+ }
+ if (max != null) {
+ leafList.getConstraints().setMaxElements(max);
+ }
+ if (unknownNodes != null) {
+ for (UnknownSchemaNodeBuilder unknown : unknownNodes) {
+ leafList.addUnknownSchemaNode(unknown);
+ }
+ }
+ } else if (refineTarget instanceof ChoiceBuilder) {
+ final ChoiceBuilder choice = (ChoiceBuilder) refineTarget;
+ if (defaultStr != null) {
+ choice.setDefaultCase(defaultStr);
+ }
+ if (mandatory != null) {
+ choice.getConstraints().setMandatory(mandatory);
+ }
+ if (unknownNodes != null) {
+ for (UnknownSchemaNodeBuilder unknown : unknownNodes) {
+ choice.addUnknownSchemaNode(unknown);
+ }
+ }
+ } else if (refineTarget instanceof AnyXmlBuilder) {
+ final AnyXmlBuilder anyXml = (AnyXmlBuilder) refineTarget;
+ if (mandatory != null) {
+ anyXml.getConstraints().setMandatory(mandatory);
+ }
+ if (must != null) {
+ anyXml.getConstraints().addMustDefinition(must);
+ }
+ if (unknownNodes != null) {
+ for (UnknownSchemaNodeBuilder unknown : unknownNodes) {
+ anyXml.addUnknownSchemaNode(unknown);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Find original builder of refine node and return copy of this builder.
+ *
+ * @param groupingPath
+ * path to grouping which contains node to refine
+ * @param refine
+ * refine object containing informations about refine
+ * @param modules
+ * all loaded modules
+ * @param module
+ * current module
+ * @return copy of Builder object of node to be refined if it is present in
+ * grouping, null otherwise
+ */
+ private Builder getRefineTargetBuilder(final String groupingPath,
+ final RefineHolder refine,
+ final Map<String, TreeMap<Date, ModuleBuilder>> modules,
+ final ModuleBuilder module) {
+ Builder result = null;
+ final Builder lookedUpBuilder = findRefineTargetBuilder(groupingPath,
+ refine.getName(), modules, module);
+ if (lookedUpBuilder instanceof LeafSchemaNodeBuilder) {
+ result = ParserUtils
+ .copyLeafBuilder((LeafSchemaNodeBuilder) lookedUpBuilder);
+ } else if (lookedUpBuilder instanceof ContainerSchemaNodeBuilder) {
+ result = ParserUtils
+ .copyContainerBuilder((ContainerSchemaNodeBuilder) lookedUpBuilder);
+ } else if (lookedUpBuilder instanceof ListSchemaNodeBuilder) {
+ result = ParserUtils
+ .copyListBuilder((ListSchemaNodeBuilder) lookedUpBuilder);
+ } else if (lookedUpBuilder instanceof LeafListSchemaNodeBuilder) {
+ result = ParserUtils
+ .copyLeafListBuilder((LeafListSchemaNodeBuilder) lookedUpBuilder);
+ } else if (lookedUpBuilder instanceof ChoiceBuilder) {
+ result = ParserUtils
+ .copyChoiceBuilder((ChoiceBuilder) lookedUpBuilder);
+ } else if (lookedUpBuilder instanceof AnyXmlBuilder) {
+ result = ParserUtils
+ .copyAnyXmlBuilder((AnyXmlBuilder) lookedUpBuilder);
+ } else {
+ throw new YangParseException("Target '" + refine.getName()
+ + "' can not be refined");
+ }
+ return result;
+ }
+
+ /**
+ * Find builder of refine node.
+ *
+ * @param groupingPath
+ * path to grouping which contains node to refine
+ * @param refineNodeName
+ * name of node to be refined
+ * @param modules
+ * all loaded modules
+ * @param module
+ * current module
+ * @return Builder object of refine node if it is present in grouping, null
+ * otherwise
+ */
+ private Builder findRefineTargetBuilder(final String groupingPath,
+ final String refineNodeName,
+ final Map<String, TreeMap<Date, ModuleBuilder>> modules,
+ final ModuleBuilder module) {
+ final SchemaPath path = ParserUtils.parseUsesPath(groupingPath);
+ final List<String> builderPath = new ArrayList<String>();
+ String prefix = null;
+ for (QName qname : path.getPath()) {
+ builderPath.add(qname.getLocalName());
+ prefix = qname.getPrefix();
+ }
+ if (prefix == null) {
+ prefix = module.getPrefix();
+ }
+
+ final ModuleBuilder dependentModule = findDependentModule(modules,
+ module, prefix);
+ builderPath.add(0, "grouping");
+ builderPath.add(0, dependentModule.getName());
+ final GroupingBuilder builder = (GroupingBuilder) dependentModule
+ .getNode(builderPath);
+
+ return builder.getChildNode(refineNodeName);
+ }
+
+ private QName findFullQName(
+ final Map<String, TreeMap<Date, ModuleBuilder>> modules,
+ final ModuleBuilder module, final IdentityrefTypeBuilder idref) {
+ QName result = null;
+ String baseString = idref.getBaseString();
+ if (baseString.contains(":")) {
+ String[] splittedBase = baseString.split(":");
+ if (splittedBase.length > 2) {
+ throw new YangParseException(
+ "Failed to parse identityref base: " + baseString);
+ }
+ String prefix = splittedBase[0];
+ String name = splittedBase[1];
+ ModuleBuilder dependentModule = findDependentModule(modules,
+ module, prefix);
+ result = new QName(dependentModule.getNamespace(),
+ dependentModule.getRevision(), prefix, name);
+ } else {
+ result = new QName(module.getNamespace(), module.getRevision(),
+ module.getPrefix(), baseString);
+ }
+ return result;
+ }
+
+ private void resolveUnknownNodes(
+ final Map<String, TreeMap<Date, ModuleBuilder>> modules,
+ final ModuleBuilder module) {
+ for (UnknownSchemaNodeBuilder usnb : module.getAddedUnknownNodes()) {
+ QName nodeType = usnb.getNodeType();
+ if (nodeType.getNamespace() == null
+ || nodeType.getRevision() == null) {
+ try {
+ ModuleBuilder dependentModule = findDependentModule(
+ modules, module, nodeType.getPrefix());
+ QName newNodeType = new QName(
+ dependentModule.getNamespace(),
+ dependentModule.getRevision(),
+ nodeType.getPrefix(), nodeType.getLocalName());
+ usnb.setNodeType(newNodeType);
+ } catch (YangParseException e) {
+ logger.debug("Failed to find unknown node type: "
+ + nodeType);
+ }
+ }
+ }
+ }
+