@Test
  public void testCreateTableNode() throws Exception {

    BaseDatabaseResourceInfo resourceInfo = mock(BaseDatabaseResourceInfo.class);
    Map<Object, Object> attributes = new HashMap<>();
    attributes.put(DictionaryConst.PROPERTY_QUERY, "select * from mytable");
    when(resourceInfo.getAttributes()).thenReturn(attributes);

    IMetaverseNode connectionNode = mock(IMetaverseNode.class);
    doReturn(connectionNode).when(analyzer).getConnectionNode();
    when(connectionNode.getLogicalId()).thenReturn("CONNECTION_ID");

    IMetaverseNode resourceNode = analyzer.createTableNode(resourceInfo);
    assertEquals("select * from mytable", resourceNode.getProperty(DictionaryConst.PROPERTY_QUERY));
    assertEquals("SQL", resourceNode.getName());
    assertEquals("CONNECTION_ID", resourceNode.getProperty(DictionaryConst.PROPERTY_NAMESPACE));
  }
  @Override
  protected void customAnalyze(JobExecutorMeta meta, IMetaverseNode node)
      throws MetaverseAnalyzerException {

    String jobPath = meta.getFileName();
    JobMeta subJobMeta = null;
    Repository repo = parentTransMeta.getRepository();

    switch (meta.getSpecificationMethod()) {
      case FILENAME:
        jobPath = parentTransMeta.environmentSubstitute(meta.getFileName());
        try {
          String normalized = KettleAnalyzerUtil.normalizeFilePath(jobPath);

          subJobMeta = getSubJobMeta(parentTransMeta, normalized);
          jobPath = normalized;

        } catch (Exception e) {
          throw new MetaverseAnalyzerException(
              "Sub transformation can not be found - " + jobPath, e);
        }
        break;
      case REPOSITORY_BY_NAME:
        if (repo != null) {
          String dir = parentTransMeta.environmentSubstitute(meta.getDirectoryPath());
          String file = parentTransMeta.environmentSubstitute(meta.getJobName());
          try {
            RepositoryDirectoryInterface rdi = repo.findDirectory(dir);
            subJobMeta = repo.loadJob(file, rdi, null, null);
            String filename =
                subJobMeta.getFilename() == null ? subJobMeta.toString() : subJobMeta.getFilename();
            jobPath = filename + "." + subJobMeta.getDefaultExtension();
          } catch (KettleException e) {
            throw new MetaverseAnalyzerException(
                "Sub transformation can not be found in repository - " + file, e);
          }
        } else {
          throw new MetaverseAnalyzerException(
              "Not connected to a repository, can't get the transformation");
        }
        break;
      case REPOSITORY_BY_REFERENCE:
        if (repo != null) {
          try {
            subJobMeta = repo.loadJob(meta.getJobObjectId(), null);
            String filename =
                subJobMeta.getFilename() == null ? subJobMeta.toString() : subJobMeta.getFilename();
            jobPath = filename + "." + subJobMeta.getDefaultExtension();
          } catch (KettleException e) {
            throw new MetaverseAnalyzerException(
                "Sub transformation can not be found by reference - " + meta.getJobObjectId(), e);
          }
        } else {
          throw new MetaverseAnalyzerException(
              "Not connected to a repository, can't get the transformation");
        }
        break;
    }

    // analyze the sub trans?

    IComponentDescriptor ds =
        new MetaverseComponentDescriptor(
            subJobMeta.getName(),
            DictionaryConst.NODE_TYPE_JOB,
            descriptor.getNamespace().getParentNamespace());

    IMetaverseNode jobNode = createNodeFromDescriptor(ds);
    jobNode.setProperty(DictionaryConst.PROPERTY_NAMESPACE, ds.getNamespaceId());
    jobNode.setProperty(DictionaryConst.PROPERTY_PATH, jobPath);
    jobNode.setLogicalIdGenerator(DictionaryConst.LOGICAL_ID_GENERATOR_DOCUMENT);

    metaverseBuilder.addLink(node, DictionaryConst.LINK_EXECUTES, jobNode);

    connectToSubJobOutputFields(meta, subJobMeta, jobNode, descriptor);

    node.setProperty(JOB_TO_EXECUTE, jobPath);

    if (StringUtils.isNotEmpty(meta.getExecutionResultTargetStep())) {
      node.setProperty(EXECUTION_RESULTS_TARGET, meta.getExecutionResultTargetStep());
    }

    /* TODO remove? if ( StringUtils.isNotEmpty( meta.getOutputRowsSourceStep() ) ) {
      node.setProperty( OUTPUT_ROWS_TARGET, meta.getOutputRowsSourceStep() );
    }*/

    if (StringUtils.isNotEmpty(meta.getResultFilesTargetStep())) {
      node.setProperty(RESULT_FILES_TARGET, meta.getResultFilesTargetStep());
    }
  }