public OntologyPath DeepCopy()
        {
            OntologyPath retval = new OntologyPath(this.startClassName);

            // create each new entry as we go...
            foreach (Triple t in this.tripleList)
            {
                retval.AddTriple(t.GetSubject(), t.GetPredicate(), t.GetObject());
            }
            return(retval);
        }
        public List <OntologyPath> FindAllPaths(String FromClassName, List <String> targetClassNames, String domain)
        {
            this.pathWarnings = new List <String>();
            List <OntologyPath> waitingList = new List <OntologyPath>();

            waitingList.Add(new OntologyPath(FromClassName));
            List <OntologyPath>      ret        = new List <OntologyPath>();
            Dictionary <String, int> targetHash = new Dictionary <String, int>(); // hash of all possible ending classes:  targetHash[className] = 1

            long t0 = DateTimeOffset.Now.ToUnixTimeMilliseconds();

            int LENGTH_RANGE     = 2;
            int SEARCH_TIME_MSEC = 5000;
            int LONGEST_PATH     = 10;

            // return if there is no endpoint
            if (targetClassNames.Count == 0)
            {
                return(ret);
            }

            // set up targetHash[targetClass] = 1
            for (int i = 0; i < targetClassNames.Count; i++)
            {
                if (!targetHash.ContainsKey(targetClassNames[i]))
                {
                    targetHash.Add(targetClassNames[i], 1);
                }
            }

            // STOP CRITERIA A: search as long as there is a waiting list
            while (waitingList.Count != 0)
            {
                // pull one off the waiting list
                OntologyPath item = waitingList[0];
                waitingList.RemoveAt(0);
                String       waitClass = item.GetEndClassName();
                OntologyPath waitPath  = item;

                // STOP CRITERIA B: also stop searching if:
                // this is the final path (with 1 added connection) will be longer than the first (shortest) already found path
                if (!(ret.Count == 0) && (waitPath.GetLength() + 1 > ret[0].GetLength() + LENGTH_RANGE))
                {
                    break;
                }

                // STOP CRITERIA C: stop if the path is too long.
                if (waitPath.GetLength() > LONGEST_PATH)
                {
                    break;
                }

                // STOP CRITERIA D: too much time spent searching.
                long tt = DateTimeOffset.Now.ToUnixTimeMilliseconds();
                if (tt - t0 > SEARCH_TIME_MSEC)
                {
                    this.pathWarnings.Add("Note: Path-finding timing out.  Search incomplete.");
                }

                // get all of the one-hop connections and loop through them.
                List <OntologyPath> conn = this.GetConnList(waitClass);
                foreach (OntologyPath currPath in conn)
                {
                    // each connection is a path with only one node (the 0th)
                    // grab the name of the newly-found class

                    String       newClass = "";
                    OntologyPath newPath  = null;
                    Boolean      loopFlag = false;

                    // if the newfound class is pointed to by an attribute of one on the wait list
                    if (currPath.GetStartClassName().ToLower().Equals(waitClass.ToLower()))
                    {
                        newClass = currPath.GetEndClassName();
                    }
                    else
                    {
                        newClass = currPath.GetStartClassName();
                    }

                    // check for loops in the path before adding the class
                    if (waitPath.ContainsClass(newClass))
                    {
                        loopFlag = true;
                    }

                    // build the new path.
                    Triple t = currPath.GetTriple(0);
                    newPath = waitPath.DeepCopy();
                    newPath.AddTriple(t.GetSubject(), t.GetPredicate(), t.GetObject());

                    // if the path leads anywhere in domain, store it.
                    OntologyName name = new OntologyName(newClass);
                    if (name.IsInDomain(domain))
                    {   // if the path leads to a target, push onth the ret list
                        if (targetHash.ContainsKey(newClass))
                        {
                            ret.Add(newPath);
                        }
                        else if (loopFlag == false)
                        {   // try extending an already found path.
                            waitingList.Add(newPath);
                        }
                    }
                }
            }
            return(ret);
        }
        public void AddJson(JsonObject encodedOInfo)
        {
            // check the version:
            long version = 0;

            if (encodedOInfo.ContainsKey("version"))
            {
                version = (long)encodedOInfo.GetNamedNumber("version");
            }
            // check the version information now
            if (version > OntologyInfo.JSON_VERSION)
            {   // fail gracelessly
                throw new Exception("Can't decode OntologyInfo JSON with newer version > " + OntologyInfo.JSON_VERSION + " : found " + version);
            }

            // get the connection, if it exists and we care.
            if (encodedOInfo.ContainsKey("sparqlConn"))
            {   // set it up.
                JsonObject       connObj = encodedOInfo.GetNamedObject("sparqlConn");
                SparqlConnection connVal = new SparqlConnection(connObj.ToString());
                this.modelConnnection = connVal;
            }

            // get the oInfo block
            if (!encodedOInfo.ContainsKey("ontologyInfo"))
            {   // panic
                throw new Exception("encoded group does not include the ontologyInfo block and cannot be used.");
            }
            JsonObject oInfoBlock = encodedOInfo.GetNamedObject("ontologyInfo");

            // unpack the prefixews
            Dictionary <String, String> prefixHash = new Dictionary <String, String>();
            JsonArray prefixes = oInfoBlock.GetNamedArray("prefixes");

            for (int i = 0; i < prefixes.Count; i++)
            {
                JsonObject currPrefix = prefixes.GetObjectAt((uint)i);
                prefixHash.Add(currPrefix.GetNamedString("prefixId"), currPrefix.GetNamedString("prefix"));
            }

            // unpack everything else. this is a little different than in the java because we do not have to use the table load
            // logic. as a result, this may be more straightforward.

            // unpack the classes:

            JsonArray classArr = oInfoBlock.GetNamedArray("classList");

            for (int m = 0; m < classArr.Count; m++)
            {   // get each class and add them... and related values...
                JsonObject currClass = classArr.GetObjectAt((uint)m);
                String     fullUri   = Utility.Utility.UnPrefixUri(currClass.GetNamedString("fullUri"), prefixHash);
                JsonArray  subC      = currClass.GetNamedArray("subClasses");
                JsonArray  superC    = currClass.GetNamedArray("superClasses");
                JsonArray  comments  = currClass.GetNamedArray("comments");
                JsonArray  labels    = currClass.GetNamedArray("labels");
                JsonArray  direct    = currClass.GetNamedArray("directConnections");

                // find or create the class.
                OntologyClass curr = null;

                if (this.classHash.ContainsKey(fullUri))
                {   // get that one.
                    curr = classHash[fullUri];
                }
                else
                {   // create a new one
                    curr = new OntologyClass(fullUri);
                    this.classHash.Add(fullUri, curr);
                }

                // create the List of parent names
                for (int pi = 0; pi < superC.Count; pi++)
                {   // check and add the superclasses
                    String pn = Utility.Utility.UnPrefixUri(superC.GetStringAt((uint)pi), prefixHash);
                    // check that the parent exists. if not, make it.
                    if (!this.classHash.ContainsKey(pn))
                    {
                        OntologyClass parentClass = new OntologyClass(pn);
                        classHash.Add(pn, parentClass);
                    }

                    // add the parent.
                    curr.AddParentName(pn);
                }

                // get the comments.
                for (int com = 0; com < comments.Count; com++)
                {
                    String c = comments.GetStringAt((uint)com);
                    curr.AddAnnotationComment(c);
                }

                // get the labels.
                for (int lab = 0; lab < labels.Count; lab++)
                {
                    String l = labels.GetStringAt((uint)lab);
                    curr.AddAnnotationLabel(l);
                }

                // add the subclasses as well...
                List <OntologyClass> children = new List <OntologyClass>();
                for (int h = 0; h < subC.Count; h++)
                {   // check and add the subclasses
                    String        cn    = Utility.Utility.UnPrefixUri(subC.GetStringAt((uint)h), prefixHash);
                    OntologyClass child = null;
                    // check that it exists. if not, make it.
                    if (!this.classHash.ContainsKey(cn))
                    {
                        OntologyClass childClass = new OntologyClass(cn);
                        classHash.Add(cn, childClass);
                        child = childClass;
                    }
                    else
                    {
                        child = this.classHash[cn];
                    }
                    children.Add(child);
                }

                // if there were any entries, add this.
                if (children.Count > 0)
                {
                    this.subclassHash.Add(fullUri, children);
                }

                // handle the connections.
                List <OntologyPath> paths = new List <OntologyPath>();
                for (int b = 0; b < direct.Count; b++)
                {   // all the one-hop connections.
                    JsonObject jdir = direct.GetObjectAt((uint)b);
                    String     destinationClassUri = Utility.Utility.UnPrefixUri(jdir.GetNamedString("destinationClass"), prefixHash);
                    String     predicateUri        = Utility.Utility.UnPrefixUri(jdir.GetNamedString("predicate"), prefixHash);
                    String     startClassUri       = Utility.Utility.UnPrefixUri(jdir.GetNamedString("startClass"), prefixHash);

                    OntologyPath op = new OntologyPath(startClassUri);
                    op.AddTriple(startClassUri, predicateUri, destinationClassUri);

                    // add to the list
                    paths.Add(op);
                }

                if (paths.Count > 0)
                {   // we have some paths. add it.
                    this.connHash.Add(fullUri, paths);
                }

                // done with the classes.
            }

            // unpack the properties:

            JsonArray propertyArr = oInfoBlock.GetNamedArray("propertyList");

            for (int j = 0; j < propertyArr.Count; j++)
            {   // add each entry to the property list.
                JsonObject currPropJson = propertyArr.GetObjectAt((uint)j);

                String    fullUri  = Utility.Utility.UnPrefixUri(currPropJson.GetNamedString("fullUri"), prefixHash);
                JsonArray comments = currPropJson.GetNamedArray("comments");
                JsonArray labels   = currPropJson.GetNamedArray("labels");
                JsonArray domain   = currPropJson.GetNamedArray("domain");
                JsonArray range    = currPropJson.GetNamedArray("range");

                // get the (currently) single range.
                String rangeUri = Utility.Utility.UnPrefixUri(range.GetStringAt(0), prefixHash);
                // create the property
                OntologyProperty oProp = new OntologyProperty(fullUri, rangeUri);

                for (int di = 0; di < domain.Count; di++)
                {   // get the domain info and add it.
                    String domainUri = Utility.Utility.UnPrefixUri(domain.GetStringAt((uint)di), prefixHash);
                    // get the class in the domain.
                    OntologyClass domClass = this.classHash[domainUri];
                    domClass.AddProperty(oProp);
                }

                // add the labels.
                for (int li = 0; li < labels.Count; li++)
                {
                    String label = labels.GetStringAt((uint)li);
                    oProp.AddAnnotationLabel(label);
                }

                // add the comments
                for (int ci = 0; ci < comments.Count; ci++)
                {
                    String comment = comments.GetStringAt((uint)ci);
                    oProp.AddAnnotationComment(comment);
                }

                this.propertyHash.Add(fullUri, oProp);
            }

            // add the enumerations
            JsonArray enumerationArr = oInfoBlock.GetNamedArray("enumerations");

            for (int ei = 0; ei < enumerationArr.Count; ei++)
            {
                JsonObject enumVal = enumerationArr.GetObjectAt((uint)ei);

                String    fullUri  = Utility.Utility.UnPrefixUri(enumVal.GetNamedString("fullUri"), prefixHash);
                JsonArray children = enumVal.GetNamedArray("enumeration");

                List <String> childUris = new List <String>();
                for (int ci = 0; ci < children.Count; ci++)
                {
                    childUris.Add(Utility.Utility.UnPrefixUri(children.GetStringAt((uint)ci), prefixHash));
                }
                // add the list
                if (childUris.Count > 0)
                {
                    this.enumerationHash.Add(fullUri, childUris);
                }
            }
        }
        public List <OntologyPath> GetConnList(String classNameStr)
        {
            // return or calculate all legal one-hop paths to and from a class
            if (!this.connHash.ContainsKey(classNameStr))
            {   // we need to calculate the connection list.
                List <OntologyPath> ret = new List <OntologyPath>();
                OntologyPath        path;

                if (!this.classHash.ContainsKey(classNameStr))
                {   // couldn't find it. panic.
                    throw new Exception("Internal error in OntologyInfo.getConnList(): class name is not in the ontology: " + classNameStr);
                }

                OntologyClass            classVal  = this.classHash[classNameStr];
                Dictionary <String, int> foundHash = new Dictionary <string, int>();
                String hashStr = "";

                // calculate the needed values.
                List <OntologyProperty> props = this.GetInheritedProperies(classVal);
                foreach (OntologyProperty prop in props)
                {
                    String rangeClassName = prop.GetRangeStr();

                    // if the range looks right
                    if (this.ContainsClass(rangeClassName))
                    {
                        // exact match classA -> hasA -> rangeClassname
                        path = new OntologyPath(classNameStr);
                        path.AddTriple(classNameStr, prop.GetNameStr(), rangeClassName);
                        hashStr = path.AsString();

                        if (!foundHash.ContainsKey(hashStr))
                        {
                            ret.Add(path);
                            foundHash.Add(hashStr, 1);
                        }

                        // sub-classes: class -> hasA -> subclass(Rangename)
                        List <String> rangeSubNames = this.GetSubclassNames(rangeClassName);
                        foreach (String jString in rangeSubNames)
                        {
                            if (this.ContainsClass(jString))
                            {
                                path = new OntologyPath(classNameStr);
                                path.AddTriple(classNameStr, prop.GetNameStr(), jString);
                                hashStr = path.AsString();
                                if (!foundHash.ContainsKey(hashStr))
                                {
                                    foundHash.Add(hashStr, 1);
                                }
                            }
                        }
                    }
                }

                // -- calculate HadBy: class which HasA classNameStr
                // store all superclasses of target class
                List <String> supList = this.GetSuperclassNames(classNameStr);

                foreach (String cname in this.classHash.Keys)
                {
                    // loop through every property
                    List <OntologyProperty> cprops = this.GetInheritedProperies(this.classHash[cname]);

                    foreach (OntologyProperty prop in cprops)
                    {
                        String rangeClassStr = prop.GetRangeStr();

                        // HadBy : cName -> hasA -> class
                        if (rangeClassStr.Equals(classNameStr))
                        {
                            path = new OntologyPath(classNameStr);
                            path.AddTriple(cname, prop.GetNameStr(), classNameStr);
                            hashStr = path.AsString();
                            if (!foundHash.ContainsKey(hashStr))
                            {
                                ret.Add(path);
                                foundHash.Add(hashStr, 1);
                            }
                        }

                        // IsA + hadBy : cName -> hasA -> superClasss (class)
                        for (int j = 0; j < supList.Count(); j++)
                        {
                            if (rangeClassStr.Equals(supList[j]))
                            {
                                path = new OntologyPath(classNameStr);
                                path.AddTriple(cname, prop.GetNameStr(), classNameStr);
                                hashStr = path.AsString();

                                if (!foundHash.ContainsKey(hashStr))
                                {
                                    ret.Add(path);
                                    foundHash.Add(hashStr, 1);
                                }
                            }
                        }
                    }
                }
                this.connHash.Add(classNameStr, ret);
            }

            return(this.connHash[classNameStr]);
        }