/**
  * List of all subproperties of the predicate parameter
  *
  * @param prop prefix namespace : name of the propoety
  * @return list<prefix:prop_name>
  */
 public List<String> listSubProp(String prop) {
   List<String> l = new ArrayList<String>();
   ExtendedIterator<OntProperty> listAllOntProperties = ontologie.listAllOntProperties();
   while (listAllOntProperties.hasNext()) {
     OntProperty next = listAllOntProperties.next();
     if (next.getLocalName().equals(prop.split(":")[1])
         && next.getNameSpace().equals(prop.split(":")[0])) {
       ExtendedIterator<? extends OntProperty> listSubProperties = next.listSubProperties();
       while (listSubProperties.hasNext()) {
         OntProperty next2 = listSubProperties.next();
         l.add(next2.getNameSpace() + ":" + next2.getLocalName());
       }
     }
   }
   return l;
 }
  public void setSubPropertyOf(Properties Properties, OntModel ontologyModel) {

    Iterator<OntProperty> IteratorExtractedProperties =
        Properties.getExtractedProperty().iterator();
    while (IteratorExtractedProperties.hasNext()) {
      OntProperty property = (OntProperty) IteratorExtractedProperties.next();
      String URI = property.getURI();

      if (URI != null) {
        try {
          ExtendedIterator<OntProperty> itSup =
              (ExtendedIterator<OntProperty>) property.listSuperProperties(true);
          while (itSup.hasNext()) {
            OntProperty propertySup = itSup.next();
            String URISUP = propertySup.getURI();

            if (URISUP != null) {
              addSubPropertyOfRelation(property, propertySup);
            }
          }
        } catch (Exception e) {
          // SPARQL Query for SubProperties
          String queryString =
              "PREFIX rdfs:<"
                  + RDFS.getURI()
                  + ">"
                  + "PREFIX ont:<"
                  + property.getNameSpace()
                  + ">"
                  + "SELECT ?obj "
                  + "WHERE {"
                  + "      ont:"
                  + property.getLocalName()
                  + " rdfs:subPropertyOf ?obj"
                  + "      }";

          // Execute Query
          Query query = QueryFactory.create(queryString);
          QueryExecution qexec = QueryExecutionFactory.create(query, ontologyModel);

          try {

            ResultSet results = qexec.execSelect();

            // Temporary Model in Order to Construct Node for External Property
            OntModel ontologyTempModel =
                ModelFactory.createOntologyModel(OntModelSpec.OWL_DL_MEM, null);

            // Extract Relation
            for (; results.hasNext(); ) {
              QuerySolution soln = results.nextSolution();

              Resource obj = soln.getResource("obj");
              String URIObj = obj.getURI();

              // Get SubPropertyOf all Property different from the current one
              if (URIObj != null && property.getURI() != URIObj) {
                OntProperty propertySup = ontologyTempModel.createOntProperty(URIObj);

                // Save SubPropertyOf Relation (property SubPropertyOf PropertySub)
                addSubPropertyOfRelation(property, propertySup);
              }
            }
          } finally {
            qexec.close();
          }
        }
      }
    }
  }
  @Override
  public UpdateContainer doIt(VWorkspace vWorkspace) throws CommandException {
    OntologyManager ontMgr = vWorkspace.getWorkspace().getOntologyManager();
    JSONArray classesList = new JSONArray();
    JSONArray classesMap = new JSONArray();
    JSONArray propertiesList = new JSONArray();
    JSONArray propertiesMap = new JSONArray();

    Map<String, String> prefixMap = vWorkspace.getWorkspace().getOntologyManager().getPrefixMap();

    ExtendedIterator<OntClass> iter = ontMgr.getOntModel().listNamedClasses();
    //		ExtendedIterator<DatatypeProperty> propsIter = ontMgr.getOntModel()
    //				.listDatatypeProperties();
    ExtendedIterator<OntProperty> propsIter = ontMgr.getOntModel().listAllOntProperties();
    final JSONObject outputObj = new JSONObject();

    try {
      while (iter.hasNext()) {
        OntClass cls = iter.next();

        String pr = prefixMap.get(cls.getNameSpace());
        String classLabel = cls.getLocalName();
        //				if (cls.getLabel(null) != null && !cls.getLabel(null).equals(""))
        //					classLabel = cls.getLabel(null);
        String clsStr = (pr != null && !pr.equals("")) ? pr + ":" + classLabel : classLabel;

        classesList.put(clsStr);
        JSONObject classKey = new JSONObject();
        classKey.put(clsStr, cls.getURI());
        classesMap.put(classKey);
      }

      while (propsIter.hasNext()) {
        //				DatatypeProperty prop = propsIter.next();
        OntProperty prop = propsIter.next();

        if (prop.isObjectProperty() && !prop.isDatatypeProperty()) continue;

        String pr = prefixMap.get(prop.getNameSpace());
        String propLabel = prop.getLocalName();
        //				if (prop.getLabel(null) != null && !prop.getLabel(null).equals(""))
        //					propLabel = prop.getLabel(null);
        String propStr = (pr != null && !pr.equals("")) ? pr + ":" + propLabel : propLabel;

        propertiesList.put(propStr);
        JSONObject propKey = new JSONObject();
        propKey.put(propStr, prop.getURI());
        propertiesMap.put(propKey);
      }

      // Populate the JSON object that will hold everything in output
      outputObj.put(JsonKeys.classList.name(), classesList);
      outputObj.put(JsonKeys.classMap.name(), classesMap);
      outputObj.put(JsonKeys.propertyList.name(), propertiesList);
      outputObj.put(JsonKeys.propertyMap.name(), propertiesMap);

    } catch (JSONException e) {
      logger.error("Error populating JSON!");
    }

    UpdateContainer upd =
        new UpdateContainer(
            new AbstractUpdate() {
              @Override
              public void generateJson(String prefix, PrintWriter pw, VWorkspace vWorkspace) {
                pw.print(outputObj.toString());
              }
            });
    return upd;
  }