All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.yangcentral.yangkit.model.impl.schema.YangSchemaContextImpl Maven / Gradle / Ivy

There is a newer version: 1.4.5
Show newest version
package org.yangcentral.yangkit.model.impl.schema;

import org.yangcentral.yangkit.base.YangBuiltinKeyword;
import org.yangcentral.yangkit.base.YangContext;
import org.yangcentral.yangkit.base.YangElement;
import org.yangcentral.yangkit.base.YangSpecification;
import org.yangcentral.yangkit.common.api.AbsolutePath;
import org.yangcentral.yangkit.common.api.QName;
import org.yangcentral.yangkit.common.api.XPathStep;
import org.yangcentral.yangkit.common.api.validate.ValidatorResult;
import org.yangcentral.yangkit.common.api.validate.ValidatorResultBuilder;
import org.yangcentral.yangkit.model.api.schema.ModuleId;
import org.yangcentral.yangkit.model.api.schema.SchemaPath;
import org.yangcentral.yangkit.model.api.schema.YangSchema;
import org.yangcentral.yangkit.model.api.schema.YangSchemaContext;
import org.yangcentral.yangkit.model.api.stmt.*;
import org.yangcentral.yangkit.model.api.stmt.Module;
import org.yangcentral.yangkit.model.impl.stmt.SchemaNodeContainerImpl;

import java.net.URI;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

public class YangSchemaContextImpl implements YangSchemaContext {
   private List modules = new ArrayList<>();
   private List importOnlyModules = new ArrayList<>();
   private Map> moduleMap = new ConcurrentHashMap<>();
   private Map> parseResult = new ConcurrentHashMap<>();
   private YangSchema schema;

   private ValidatorResult validatorResult;
   private SchemaNodeContainerImpl schemaNodeContainer = new SchemaNodeContainerImpl(null);

   public List getModules() {
      return this.modules;
   }

   public List getImportOnlyModules() {
      return this.importOnlyModules;
   }

   public YangSchemaContextImpl(YangSchema schema) {
      this.schema = schema;
   }

   public YangSchemaContextImpl() {
   }


   public Optional getModule(String name, String revision) {
      return this.getModule(new ModuleId(name, revision));
   }

   public Optional getModule(ModuleId moduleId) {
      if (!this.moduleMap.containsKey(moduleId.getModuleName())) {
         return Optional.empty();
      }
      if(moduleId.getRevision() == null || moduleId.getRevision().equals("")){
         return getLatestModule(moduleId.getModuleName());
      }
      List modules = getModule(moduleId.getModuleName());
      for (Module module:modules) {
         if(module.getModuleId().equals(moduleId)){
            return Optional.of(module);
         }
      }
      return Optional.empty();
   }

   public List getModule(String name) {
      return this.moduleMap.get(name);
   }

   @Override
   public Optional getLatestModule(String name) {
      List modules = getModule(name);
      if(modules == null || modules.isEmpty()){
         return Optional.empty();
      }
      Module latestModule = null;
      for(Module module:modules){
         if(latestModule == null){
            latestModule = module;
            continue;
         }
         if(!latestModule.getCurRevisionDate().isPresent()){
            latestModule = module;
            continue;
         }
         if(!module.getCurRevisionDate().isPresent()){
            continue;
         }

         if(module.getCurRevisionDate().get().compareTo(latestModule.getCurRevisionDate().get())>0){
            latestModule = module;
         }

      }
      return Optional.of(latestModule);
   }

   public List getModule(URI namespace) {
      List candidate = new ArrayList<>();
      Iterator> valueIt = this.moduleMap.values().iterator();

      while(true) {
         List modules;
         do {
            if (!valueIt.hasNext()) {
               return candidate;
            }

            modules = valueIt.next();
         } while(null == modules);

         for (Module module : modules) {
            if (module.getMainModule() != null) {
               URI uri = module.getMainModule().getNamespace().getUri();
               if (uri.equals(namespace)) {
                  candidate.add(module);
               }
            }
         }
      }
   }

   public Optional getSchemaNode(SchemaPath.Absolute path) {
      SchemaNode schemaNode = path.getSchemaNode(this);
      return null == schemaNode ? Optional.empty() : Optional.of(schemaNode);
   }

   @Override
   public SchemaNode getSchemaNode(AbsolutePath absolutePath) {
      if(absolutePath == null || absolutePath.isRootPath()){
         return null;
      }
      SchemaNodeContainer schemaNodeContainer = this;
      int size = absolutePath.getSteps().size();
      for(int i=0; i < size; i++){
         XPathStep step = absolutePath.getSteps().get(i);
         QName stepName = step.getStep();
         SchemaNode schemaNode = schemaNodeContainer.getDataNodeChild(stepName);
         if(schemaNode == null){
            break;
         }
         if(i == (size-1)){
            return schemaNode;
         }
         if(schemaNode instanceof SchemaNodeContainer){
            schemaNodeContainer = (SchemaNodeContainer) schemaNode;
         } else {
            break;
         }
      }

      return null;
   }

   public YangSchema getYangSchema() {
      return this.schema;
   }

   @Override
   public void setYangSchema(YangSchema yangSchema) {
      this.schema = yangSchema;
   }

   public void addModule(Module module) {
      if(getModule(module.getModuleId()).isPresent()) {
         Module matchedModule = getModule(module.getModuleId()).get();
         if(isImportOnly(matchedModule)){
            removeModule(matchedModule.getModuleId());
         } else {
            return;
         }
      }
      this.modules.add(module);
      List filterModules = this.moduleMap.get(module.getArgStr());
      if(filterModules == null || filterModules.isEmpty()) {
         filterModules = new ArrayList<>();
         this.moduleMap.put(module.getArgStr(), filterModules);
      }
      filterModules.add(module);

   }

   public void addImportOnlyModule(Module module) {
      if(isImportOnly(module)){
         return;
      }
      importOnlyModules.add(module);
      if(getModule(module.getModuleId()).isPresent()){
         return;
      }
      List filterModules = this.moduleMap.get(module.getArgStr());
      if(filterModules == null || filterModules.isEmpty()) {
         filterModules = new ArrayList<>();
         this.moduleMap.put(module.getArgStr(), filterModules);
      }
      filterModules.add(module);

   }

   public boolean isImportOnly(Module module) {
      Iterator iterator = this.importOnlyModules.iterator();

      Module importOnlyModule;
      do {
         if (!iterator.hasNext()) {
            return false;
         }

         importOnlyModule = iterator.next();
      } while(importOnlyModule != module);

      return true;
   }

   public Module removeModule(ModuleId moduleId) {
      if (!this.moduleMap.containsKey(moduleId.getModuleName())) {
         return null;
      }
      List filterModules = this.moduleMap.get(moduleId.getModuleName());
      Module matchedModule = null;

      for (Module module : filterModules) {
         if (module.getModuleId().equals(moduleId)) {
            matchedModule = module;
            break;
         }
      }

      if (matchedModule == null) {
         return null;
      }
      filterModules.remove(matchedModule);
      for(SchemaNode schemaNode:matchedModule.getSchemaNodeChildren()){
         this.removeSchemaNodeChild(schemaNode);
      }
      this.modules.remove(matchedModule);
      this.importOnlyModules.remove(matchedModule);
      return matchedModule;
   }

   public Map> getParseResult() {
      return this.parseResult;
   }

   public SchemaNode getMandatoryDescendant() {
      return this.schemaNodeContainer.getMandatoryDescendant();
   }

   public void buildDependencies(){
      List modules = new ArrayList<>();
      modules.addAll(this.getModules());
      modules.addAll(this.getImportOnlyModules());
      for(Module module:modules){
         if(module == null){
            continue;
         }
         module.getDependentBys().clear();
      }
      for(Module module:modules){
         if(module == null){
            continue;
         }
         List imports = module.getSubStatement(YangBuiltinKeyword.IMPORT.getQName());
         for(YangStatement statement:imports){
            Import im = (Import) statement;
            String moduleName = im.getArgStr();
            String revisionDate = null;
            List revisionDates = im.getSubStatement(YangBuiltinKeyword.REVISIONDATE.getQName());
            if(!revisionDates.isEmpty()){
               revisionDate = revisionDates.get(0).getArgStr();
            }

            Optional importModuleOp = this.getModule(moduleName,revisionDate);
            if(importModuleOp.isPresent()){
               module.addDependency(importModuleOp.get());
               importModuleOp.get().addDependentBy(module);
            }
         }
      }
   }

   private void clear(Module module){
      try {
         module.clear();
      } catch (RuntimeException e){
         System.out.println("clear module:"+ module.getArgStr() + " failed. detail:"+e.getMessage());
      }



   }
   /**
    * validate yang schema context, it will initial all statements (init fields from argument and sub statements),
    * and build all init statements(build linkage,check static grammar,build schema tree,etc.), and then it will validate
    * all statements of all modules(in this phase, it will only check whether the relation between statements is correct,
    * for example, check whether the xpath expression is correct.)
    * @return the result of validation
    */
   public ValidatorResult validate() {
      ValidatorResultBuilder validatorResultBuilder = new ValidatorResultBuilder();
      List modules = new ArrayList<>();
      modules.addAll(this.getModules());
      modules.addAll(this.getImportOnlyModules());
      buildDependencies();
      for(Module module:modules){
         if(module.changed()){
            clear(module);
         }
      }
      //init
      for(Module module:modules){
         if(module.getContext() == null){
            module.setContext(new YangContext(this,module));
         }
         ValidatorResult result = module.init();
         validatorResultBuilder.merge(result);
      }

      //build
      for(Module module:modules){
         if((module instanceof SubModule)
                 && (module.getContext().getYangSpecification() == YangSpecification.getVersion11Spec())){
            //yang1.1, a submodule MUST be built by the module it belongs to.
            continue;
         }
         ValidatorResult result = module.build();
         validatorResultBuilder.merge(result);
      }
      //validate
      for(Module module:modules){
         validatorResultBuilder.merge(module.validate());
         validatorResultBuilder.merge(module.afterValidate());
      }
      ValidatorResult validatorResult = validatorResultBuilder.build();
      this.validatorResult = validatorResult;
      return validatorResult;
   }

   public ValidatorResult getValidateResult() {
      return validatorResult;
   }

   public List getSchemaNodeChildren() {
      return this.schemaNodeContainer.getSchemaNodeChildren();
   }

   public ValidatorResult addSchemaNodeChild(SchemaNode schemaNode) {
      if(isImportOnly(schemaNode.getContext().getCurModule())){
         return new ValidatorResultBuilder().build();
      }
      return this.schemaNodeContainer.addSchemaNodeChild(schemaNode);
   }

   public ValidatorResult addSchemaNodeChildren(List schemaNodes) {
      ValidatorResultBuilder validatorResultBuilder = new ValidatorResultBuilder();

      for (SchemaNode schemaNode : schemaNodes) {
         validatorResultBuilder.merge(this.addSchemaNodeChild(schemaNode));
      }

      return validatorResultBuilder.build();
   }

   public SchemaNode getSchemaNodeChild(QName identifier) {
      return this.schemaNodeContainer.getSchemaNodeChild(identifier);
   }

   public DataNode getDataNodeChild(QName identifier) {
      return this.schemaNodeContainer.getDataNodeChild(identifier);
   }

   public List getDataNodeChildren() {
      return this.schemaNodeContainer.getDataNodeChildren();
   }

   @Override
   public List getTreeNodeChildren() {
      return schemaNodeContainer.getTreeNodeChildren();
   }

   @Override
   public SchemaNode getTreeNodeChild(QName identifier) {
      return schemaNodeContainer.getTreeNodeChild(identifier);
   }

   @Override
   public List getEffectiveSchemaNodeChildren(boolean ignoreNamespace) {
      return schemaNodeContainer.getEffectiveSchemaNodeChildren(ignoreNamespace);
   }

   @Override
   public List getEffectiveSchemaNodeChildren() {
      return schemaNodeContainer.getEffectiveSchemaNodeChildren(true);
   }
   public void removeSchemaNodeChild(QName identifier) {
      this.schemaNodeContainer.removeSchemaNodeChild(identifier);
   }

   public void removeSchemaNodeChild(SchemaNode schemaNode) {
      this.schemaNodeContainer.removeSchemaNodeChild(schemaNode);
   }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy