private void ParseCompoundsInside(string path) { this.currentFileName = @"..\..\javadoc\html\" + path.Substring(2); HtmlDocument document = new HtmlDocument(); try { document.Load(currentFileName); } catch (Exception) { this.Log(LogKind.Warning, "Can't open " + path); return; } HtmlNode root = document.DocumentNode; // Get the HtmlNode, what represents the html tag HtmlNode htmlnode = root.ChildNodes.First(node => node.Name == "html"); HtmlNode bodyNode = null; try { bodyNode = htmlnode.ChildNodes.First(node => node.Name == "body"); } // If the aren't any body tag, than the html is invalid or corrupted catch (InvalidOperationException iox) { this.Log(LogKind.Error, "Missing body tag in the html."); return; } //Get the node, what contains the class data HtmlNode compoundDivNode = null; try { compoundDivNode = bodyNode.ChildNodes.First(node => node.Name == "div" && node.Attributes.FirstOrDefault(attr => attr.Name == "class" && attr.Value == "contentContainer") != null); } catch (InvalidOperationException iox) { this.Log(LogKind.Error, "Missing data of the coumpound can't find."); return; } String compoundname = path.Split('/')[2]; compoundname = compoundname.Remove(compoundname.Length - 5); String packagename = path.Split('/')[1]; DoxNamespace ns = (DoxNamespace)Model.Compounds.First(c => c.Name == packagename); Compound comp = (Compound)Model.Compounds.First(c => c.Identifier == ns.Name + "_" + compoundname); string Type = comp.Kind.ToString(); DoxClassifier dc; if (Type == "Class") { dc = (DoxClass)comp; } else if (Type == "Interface") { dc = (DoxInterface)comp; } else if (Type == "Exception" || Type == "Error") { dc = comp as DoxClass; } else if (Type == "Enum") { dc = (DoxEnum)comp; } else { this.Log(LogKind.Warning, Type + " isn't a valid compound type."); return; } //Read description of the compound HtmlNode description = null; HtmlNode compoundtypeparameters = null; try { description = compoundDivNode.ChildNodes.First(node => node.Name == "div" && node.Attributes.FirstOrDefault(attr => attr.Name == "class" && attr.Value == "description") != null); } catch (InvalidOperationException iox) { } if (description != null) { try { compoundtypeparameters = description.ChildNodes.First(node => node.Name == "ul").ChildNodes.First(node => node.Name == "li"); foreach (HtmlNode typeparam in compoundtypeparameters.ChildNodes.Where(node => node.Name == "dl")) { // Get all implemented interface HtmlNode type = typeparam.ChildNodes.First(node => node.Name == "dt"); if (type.InnerText == "All Implemented Interfaces:") { HtmlNode interfaces = typeparam.ChildNodes.First(node => node.Name == "dd"); foreach (HtmlNode interf in interfaces.ChildNodes.Where(node => node.Name == "a")) { // Save a reference of the interface to the compound String interfacepath = interf.Attributes.First(attr => attr.Name == "href").Value; String package = interfacepath.Split('/')[1]; String name = interfacepath.Split('/')[2]; name = name.Remove(name.Length - 5); DoxReference dr = new DoxReference(); dr.Compound = (Compound)Model.Compounds.First(c => c.Identifier == package + "_" + name); dr.External = true; dr.Text = normalizeHtml(interf.InnerText); dc.BaseClassifiers.Add(dr); } } //Save a reference of the know subclasses else if (type.InnerText == "Direct Known Subclasses:") { HtmlNode interfaces = typeparam.ChildNodes.First(node => node.Name == "dd"); foreach (HtmlNode interf in interfaces.ChildNodes.Where(node => node.Name == "a")) { String subclasspath = interf.Attributes.First(attr => attr.Name == "href").Value; String package = subclasspath.Split('/')[1]; String name = subclasspath.Split('/')[2]; name = name.Remove(name.Length - 5); DoxReference dr = new DoxReference(); dr.Compound = (Compound)Model.Compounds.First(c => c.Identifier == package + "_" + name); dr.External = true; dr.Text = normalizeHtml(interf.InnerText); dc.DerivedClassifiers.Add(dr); } } } } catch (InvalidOperationException iox) { } try { //Get direct data of the compound HtmlNode compoundproperty = compoundtypeparameters.ChildNodes.First(node => node.Name == "pre"); String compoundData = normalizeHtml(compoundproperty.ChildNodes.First(node => node.Name == "#text").InnerText); String[] compoundDatas = compoundData.Split(' '); dc.Abstract = compoundDatas.Any(str => str == "abstact"); dc.Final = compoundDatas.Any(str => str == "final"); if (compoundDatas.Any(str => str == "public")) { dc.ProtectionKind = ProtectionKind.Public; } else if (compoundDatas.Any(str => str == "protected")) { dc.ProtectionKind = ProtectionKind.Protected; } else if (compoundDatas.Any(str => str == "private")) { dc.ProtectionKind = ProtectionKind.Private; } dc.Sealed = compoundDatas.Any(str => str == "sealed"); // Get extends and implemets compounds bool extend = false; foreach (var Node in compoundproperty.ChildNodes) { if (Node.Name == "#text" && Node.InnerText.Equals("extends ")) { extend = true; } else if (Node.Name == "#text" && Node.InnerText.Equals("implements ")) { extend = false; break; } else if (Node.Name == "a") { String subclasspath = Node.Attributes.First(attr => attr.Name == "href").Value; String package = subclasspath.Split('/')[1]; String name = subclasspath.Split('/')[2]; name = name.Remove(name.Length - 5); if (extend) { // Avoid duplication, try to get the base compound Compound oldCOmpound = dc.BaseClassifiers.FirstOrDefault(c => c.Compound.Identifier == package + "_" + name).Compound; if (oldCOmpound == null) { DoxReference dr = new DoxReference(); dr.Compound = (Compound)Model.Compounds.First(c => c.Identifier == package + "_" + name); dr.External = true; dr.Text = normalizeHtml(Node.InnerText); dc.DerivedClassifiers.Add(dr); } } } } } catch (InvalidOperationException iox) { this.Log(LogKind.Error, "There isn't any data of the compound."); return; } HtmlNode[] MemberTableLiNode = null; try { MemberTableLiNode = compoundDivNode.ChildNodes.First(node => node.Name == "div" && node.Attributes.FirstOrDefault(attr => attr.Name == "class" && attr.Value == "summary") != null).ChildNodes.First(node => node.Name == "ul").ChildNodes.First(node => node.Name == "li").ChildNodes.Where(node => node.Name == "ul").ToArray(); foreach (HtmlNode MemberTable in MemberTableLiNode) { HtmlNode TypeTable = MemberTable.ChildNodes.First(node => node.Name == "li"); // Get the type of the short description (method, field or constructor). String type = TypeTable.ChildNodes.First(node => node.Name == "a").Attributes.First(attr => attr.Name == "name").Value; // Get the HtmlNode, where the table of the member is. if (type == "nested.class.summary" || TypeTable.ChildNodes.FirstOrDefault(node => node.Name == "table")==null) { continue; } HtmlNode MemTable = TypeTable.ChildNodes.First(node => node.Name == "table"); foreach (HtmlNode MemberRow in MemTable.ChildNodes.Where(node => node.Name == "tr")) { HtmlNode[] rowData = MemberRow.ChildNodes.Where(node => node.Name != "th" && node.Name != "#text").ToArray(); if(rowData.Length == 0) { continue; } DoxMember dm = null; switch (type) { // Summary of the fields case "field.summary": dm = new DoxField(); // Every line should be parsed diferrently and the '\r' character should deleted. String[] nameAndDescription = rowData[1].InnerText.Replace("\r", string.Empty).Split('\n'); // Int he first col, there is the name of the field dm.Name = normalizeHtml(nameAndDescription[0]).Replace(" ", string.Empty); HtmlNode descNode = rowData[1].ChildNodes.FirstOrDefault(node => node.Name == "div"); if(descNode != null) { //BriefDescription dm.BriefDescription = this.getDescription(descNode); } dm.DetailedDescription = new Description(); dm.Identifier = packagename + "_" + compoundname + "_" + dm.Name; String[] properties = normalizeHtml(rowData[0].InnerText).Split(' '); DoxReference dr = new DoxReference(); foreach (String item in properties) { switch (item) { case "const": dm.Const = true; break; case "final": dm.Final = true; break; case "public": dm.ProtectionKind = ProtectionKind.Public; break; case "protected": dm.ProtectionKind = ProtectionKind.Protected; break; case "private": dm.ProtectionKind = ProtectionKind.Private; break; case "sealed": dm.Sealed = true; break; case "static": dm.Sealed = true; break; default: String[] typeRoute = item.Replace("...","…").Split('.'); dm.Definition = typeRoute[typeRoute.Length-1].Replace(dm.Name,string.Empty); //this.Log(LogKind.Info, item + " used as type."); //Here need to be implented the set of the type. break; } } if(dm.VirtualKind == null) { dm.ProtectionKind = ProtectionKind.Package; } dc.Members.Add(dm); MemberIndex mi = new MemberIndex(); mi.Identifier = dm.Identifier; mi.Kind = dm.Kind; mi.Name = dm.Name; mi.Member = dm; this.Model.MemberRefs.Add(dm.Identifier, dm); this.Index.MemberIndexRefs.Add(dm.Identifier, mi); break; case "constructor.summary": dm = new DoxMethod(); nameAndDescription = normalizeHtml(rowData[0].InnerText).Split('\n'); dm.Name = normalizeHtml(rowData[0].FirstChild.FirstChild.FirstChild.InnerText); dm.ArgsString = normalizeHtml(rowData[0].ChildNodes.First(node => node.Name == "code").InnerText); dm.ArgsString = dm.ArgsString.Replace(dm.Name, string.Empty); descNode = rowData[0].ChildNodes.FirstOrDefault(node => node.Name == "div"); if(descNode != null) { //String desc = descNode.InnerText; dm.BriefDescription = this.getDescription(descNode); } dm.DetailedDescription = new Description(); dm.Identifier = packagename + "_" + compoundname + "_" + dm.Name + "_" + getId(dm.ArgsString); dc.Members.Add(dm); mi = new MemberIndex(); mi.Identifier = dm.Identifier; mi.Kind = dm.Kind; mi.Name = dm.Name; mi.Member = dm; this.Model.MemberRefs.Add(dm.Identifier, dm); this.Index.MemberIndexRefs.Add(dm.Identifier, mi); break; case "method.summary": dm = new DoxMethod(); dm = new DoxMethod(); dm.Name = normalizeHtml(rowData[1].FirstChild.FirstChild.FirstChild.InnerText); string[] returnTypeAndVisibility = normalizeHtml(rowData[0].InnerText).Split(' '); foreach (String item in returnTypeAndVisibility) { switch (item) { case "const": dm.Const = true; break; case "final": dm.Final = true; break; case "public": dm.ProtectionKind = ProtectionKind.Public; break; case "protected": dm.ProtectionKind = ProtectionKind.Protected; break; case "private": dm.ProtectionKind = ProtectionKind.Private; break; case "sealed": dm.Sealed = true; break; case "static": dm.Static = true; break; default: String[] typeRoute = item.Replace("...","…").Split('.'); dm.Definition = typeRoute[typeRoute.Length-1].Replace(dm.Name, string.Empty); //this.Log(LogKind.Info, item + " used as method type."); //Here need to be implented the set of the type. break; } } nameAndDescription = normalizeHtml(rowData[1].InnerText).Replace("\r",string.Empty).Split('\n'); dm.ArgsString = normalizeHtml(rowData[1].ChildNodes.First(node => node.Name == "code").InnerText); dm.ArgsString = dm.ArgsString.Replace(dm.Name, string.Empty); descNode = rowData[1].ChildNodes.FirstOrDefault(node => node.Name == "div"); if(descNode != null) { dm.BriefDescription = this.getDescription(descNode); } dm.DetailedDescription = new Description(); dm.Identifier = packagename + "_" + compoundname + "_" + dm.Name + "_" + getId(dm.ArgsString); dc.Members.Add(dm); mi = new MemberIndex(); mi.Identifier = dm.Identifier; mi.Kind = dm.Kind; mi.Name = dm.Name; mi.Member = dm; this.Model.MemberRefs.Add(dm.Identifier, dm); this.Index.MemberIndexRefs.Add(dm.Identifier, mi); break; case "enum.constant.summary": DoxEnumValue dev = new DoxEnumValue(); HtmlNode nameNode = rowData[0].ChildNodes.FirstOrDefault(node => node.Name == "code"); if (rowData[0].ChildNodes.FirstOrDefault(node => node.Name == "div") != null) { dev.Name = normalizeHtml(nameNode.InnerText); dm.BriefDescription = this.getDescription(rowData[0].ChildNodes.First(node => node.Name == "div")); } else { dev.Name = normalizeHtml(rowData[0].InnerText); } dev.Kind = MemberKind.EnumValue; dev.Identifier = packagename + "_" + compoundname + "_" + dev.Name.Replace(" ",string.Empty); dc.Members.Add(dev); mi = new MemberIndex(); mi.Identifier = dev.Identifier; mi.Kind = dev.Kind; mi.Name = dev.Name; mi.Member = dev; this.Model.MemberRefs.Add(dev.Identifier, dev); this.Index.MemberIndexRefs.Add(dev.Identifier, mi); break; default: this.Log(LogKind.Error, "Not implemented member type: " + type); break; } } } } catch (InvalidOperationException iox) { this.Log(LogKind.Warning, iox.Message); } // Get the brief description of the compound. try { HtmlNode BriefDescription = compoundtypeparameters.ChildNodes.First(node => node.Name == "div" && node.Attributes.FirstOrDefault(attr => attr.Name == "class" && attr.Value == "block") != null); dc.BriefDescription = this.getDescription(BriefDescription); //!! Change in the future. <code> -> Emphasis; <a> -> reference inside of the description } catch (InvalidOperationException iox) { // There is no brief description } try { HtmlNode details = compoundDivNode.ChildNodes.First(Node => Node.Name == "div" && Node.Attributes.FirstOrDefault(Attr => Attr.Name=="class" && Attr.Value == "details")!= null); HtmlNode detailsList = details.ChildNodes.First(Node => Node.Name == "ul").ChildNodes.First(Node => Node.Name == "li"); foreach (HtmlNode memberDetailTable in detailsList.ChildNodes.Where(Node => Node.Name == "ul")) { HtmlNode detailsData = memberDetailTable.ChildNodes.First(Node => Node.Name == "li"); String type = detailsData.ChildNodes.First(Node => Node.Name == "a").Attributes.First(Attr => Attr.Name=="name").Value; foreach (HtmlNode memberDetail in detailsData.ChildNodes.Where(Node => Node.Name == "ul")) { HtmlNode detailListItem = memberDetail.ChildNodes.First(Node => Node.Name == "li"); // Name of the member String name = normalizeHtml(detailListItem.ChildNodes.First(Node => Node.Name == "h4").InnerText); switch (type) { case "field.detail": String[] datas = normalizeHtml(detailListItem.ChildNodes.First(Node => Node.Name == "pre").InnerText).Split(' '); datas = datas.Where(s => s != name).ToArray(); DoxField currentMember = (DoxField)dc.Members.FirstOrDefault(c => c.Identifier == packagename + "_" + compoundname + "_" + name); foreach (String data in datas) { switch (data) { case "public": currentMember.ProtectionKind = ProtectionKind.Public; break; case "private": currentMember.ProtectionKind = ProtectionKind.Private; break; case "protected": currentMember.ProtectionKind = ProtectionKind.Protected; break; case "constant": currentMember.Const = true; break; case "static": currentMember.Static = true; break; case "volatile": currentMember.Volatile = true; break; case "final": currentMember.Final = true; break; default: break; } } if (currentMember.ProtectionKind == null) { currentMember.ProtectionKind = ProtectionKind.Package; } if (detailListItem.ChildNodes.FirstOrDefault(Node => Node.Name == "div" && Node.Attributes.FirstOrDefault(Attr => Attr.Name == "class" && Attr.Value == "block") != null) != null) { currentMember.DetailedDescription =this.getDescription(detailListItem.ChildNodes.FirstOrDefault(Node => Node.Name == "div" && Node.Attributes.FirstOrDefault(Attr => Attr.Name == "class" && Attr.Value == "block") != null)); } break; case "constructor.detail": case "method.detail": datas = normalizeHtml(detailListItem.ChildNodes.First(Node => Node.Name == "pre").InnerText).Split('('); String argsList = datas[datas.Length-1].Split(')')[0]; String ID = getId(argsList); DoxMethod currentMethod = (DoxMethod)dc.Members.FirstOrDefault(c => c.Identifier == packagename + "_" + compoundname + "_" + name + "_" + ID); String[] visibilitydatas = datas[0].Split(' ').Where(c => c != name).ToArray(); foreach (String data in visibilitydatas) { switch (data) { case "public": currentMethod.ProtectionKind = ProtectionKind.Public; break; case "private": currentMethod.ProtectionKind = ProtectionKind.Private; break; case "protected": currentMethod.ProtectionKind = ProtectionKind.Protected; break; case "constant": currentMethod.Const = true; break; case "static": currentMethod.Static = true; break; case "volatile": currentMethod.Volatile = true; break; case "final": currentMethod.Final = true; break; default: break; } } foreach (string arg in argsList.Replace(" ",string.Empty).Split(',')) { if(String.IsNullOrEmpty(arg)) { continue; } DoxParam dp = new DoxParam(); DoxLinkedText dlt = new DoxLinkedText(); DoxLinkedTextItem dlti = new DoxLinkedTextItem(); String[] relativeroute = arg.Replace("\n",string.Empty).Replace("\r",string.Empty).Replace("...","…").Split('.'); dlti.Text = relativeroute[relativeroute.Length-1].Split(' ')[0]; dlt.Items.Add(dlti); dp.Type = dlt; dp.DeclarationName = relativeroute[relativeroute.Length-1].Split(' ')[1]; currentMethod.Params.Add(dp); } if(currentMethod.ProtectionKind == null) { currentMethod.ProtectionKind = ProtectionKind.Package; } HtmlNode briefDescriptionNode = detailListItem.ChildNodes.FirstOrDefault(Node => Node.Name == "div" && Node.Attributes.FirstOrDefault(Attr => Attr.Name == "class" && Attr.Value == "block") != null); HtmlNode extraDetails = detailListItem.ChildNodes.FirstOrDefault(Node => Node.Name == "dl"); if (briefDescriptionNode != null && extraDetails != null) { currentMethod.DetailedDescription = this.getDescription(briefDescriptionNode); currentMethod.DetailedDescription.Paragraphs.AddRange(this.getDescription(extraDetails).Paragraphs); } else if (briefDescriptionNode != null) { currentMethod.DetailedDescription = this.getDescription(briefDescriptionNode); } else if(extraDetails != null) { currentMethod.DetailedDescription = this.getDescription(extraDetails); } break; case "enum.constant.detail": datas = normalizeHtml(detailListItem.ChildNodes.First(Node => Node.Name == "pre").InnerText).Split('('); DoxEnumValue currentEnum = (DoxEnumValue)dc.Members.FirstOrDefault(c => c.Identifier == packagename + "_" + compoundname + "_" + name); visibilitydatas = datas[0].Split(' ').Where(c => c != name).ToArray(); foreach (String data in visibilitydatas) { switch (data) { case "public": currentEnum.ProtectionKind = ProtectionKind.Public; break; case "private": currentEnum.ProtectionKind = ProtectionKind.Private; break; case "protected": currentEnum.ProtectionKind = ProtectionKind.Protected; break; case "constant": currentEnum.Const = true; break; case "static": currentEnum.Static = true; break; case "volatile": currentEnum.Volatile = true; break; case "final": currentEnum.Final = true; break; default: currentEnum.Definition = data; break; } } if (currentEnum.ProtectionKind == null) { currentEnum.ProtectionKind = ProtectionKind.Package; } briefDescriptionNode = detailListItem.ChildNodes.FirstOrDefault(Node => Node.Name == "div" && Node.Attributes.FirstOrDefault(Attr => Attr.Name == "class" && Attr.Value == "block") != null); extraDetails = detailListItem.ChildNodes.FirstOrDefault(Node => Node.Name == "dl"); if (briefDescriptionNode != null && extraDetails != null) { currentEnum.DetailedDescription = this.getDescription(briefDescriptionNode); currentEnum.DetailedDescription.Paragraphs.AddRange(this.getDescription(extraDetails).Paragraphs); } else if (briefDescriptionNode != null) { currentEnum.DetailedDescription = this.getDescription(briefDescriptionNode); } else if(extraDetails != null) { currentEnum.DetailedDescription = this.getDescription(extraDetails); } break; default: this.Log(LogKind.Error, type + "isn't processed"); break; } } } } catch (Exception ex) { this.Log(LogKind.Warning, ex.Message); } } }
private void parseMethod(MethodInfo[] methods, DoxClassifier dc) { foreach (MethodInfo method in methods) { if(method.Name.Length > 4) { if(method.Name.Substring(0,4).Equals("get_") || method.Name.Substring(0,4).Equals("set_")) { continue; } else if (method.Name.First().Equals('<') || method.Name.Contains("<>")) { continue; } } DoxMethod dp = new DoxMethod(); dp.Name = method.Name; dp.Identifier = dc.Identifier.Replace('+','.') + "." + dp.Name; String xmlName = dp.Identifier; ParameterInfo[] parameters = method.GetParameters(); if (method.ReturnType.GenericTypeArguments.Length > 0) { String type = method.ReturnType.Name.Substring(0, method.ReturnType.Name.Length - 2); type = type + '<'; bool first = true; foreach (var item in method.ReturnType.GenericTypeArguments) { if (first) { type = type + item.Name; first = false; } else { type = type + ", " + item.Name; } } type = type + '>'; dp.Definition = type; } else { dp.Definition = method.ReturnType.Name; } if(parameters.Length > 0) { xmlName += "("; } foreach (ParameterInfo param in parameters) { DoxLinkedTextItem dlti = new DoxLinkedTextItem(); if (param.ParameterType.GenericTypeArguments.Length > 0) { String type = param.ParameterType.Name.Substring(0, param.ParameterType.Name.Length - 2); type = type + '<'; bool first = true; foreach (var item in param.ParameterType.GenericTypeArguments) { if (first) { type = type + item.Name; first = false; } else { type = type + ", " + item.Name; } } type = type + '>'; dlti.Text = type; dp.Identifier = dp.Identifier + '_' + type; } else { dlti.Text = param.ParameterType.Name; dp.Identifier = dp.Identifier + '_' + dlti.Text; } if (param != parameters.Last()) { if (param.ParameterType.FullName != null) { xmlName += param.ParameterType.FullName.Replace('+', '.') + ","; } else { xmlName += param.ParameterType.Name.Replace('+', '.') + ","; } } else { if (param.ParameterType.FullName != null) { xmlName += param.ParameterType.FullName.Replace('+', '.') + ")"; } else { xmlName += param.ParameterType.Name.Replace('+', '.') + ")"; } } DoxLinkedText dlt = new DoxLinkedText(); dlt.Items.Add(dlti); DoxParam DPara = new DoxParam(); DPara.DeclarationName = param.Name; DPara.Type = dlt; dp.Params.Add(DPara); } String[] attributes = method.Attributes.ToString().Replace(" ", string.Empty).Split(','); foreach (string attr in attributes) { switch (attr) { case "Abstract": dp.VirtualKind = VirtualKind.Abstract; break; case "Final": dp.Final = true; break; case "Public": dp.ProtectionKind = ProtectionKind.Public; break; case "Protected": case "Family": dp.ProtectionKind = ProtectionKind.Protected; break; case "Private": dp.ProtectionKind = ProtectionKind.Private; break; case "Static": dp.Static = true; break; case "Virtual": dp.VirtualKind = VirtualKind.Virtual; break; case "Serializable": case "Sealed": case "AutoLayout": case "AnsiClass": case "Class": case "SequentialLayout": case "BeforeFieldInit": case "PrivateScope": case "HideBySig": case "SpecialName": case "VtableLayoutMask": case "Assembly": case "CheckAccessOnOverride": break; default: this.Log(LogKind.Warning, attr + " can't be processed as attribute of porpoerty."); break; } } dc.Members.Add(dp); getDescription(xmlName, DescriptionType.Detailed); getDescription(xmlName, DescriptionType.Brief); MemberIndex mi = new MemberIndex(); mi.Identifier = dp.Identifier; mi.Kind = dp.Kind; mi.Member = dp; mi.Name = dp.Name; try { this.Model.MemberRefs.Add(dp.Identifier, dp); } catch (Exception) { continue; } this.Index.MemberIndexRefs.Add(dp.Identifier, mi); } }