diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/visualization/coauthorship/CoAuthorshipGraphMLWriter.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/visualization/coauthorship/CoAuthorshipGraphMLWriter.java index 9c66252d..46d8dfdd 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/visualization/coauthorship/CoAuthorshipGraphMLWriter.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/visualization/coauthorship/CoAuthorshipGraphMLWriter.java @@ -2,6 +2,8 @@ package edu.cornell.mannlib.vitro.webapp.visualization.coauthorship; +import java.io.OutputStreamWriter; +import java.io.StringWriter; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -16,45 +18,77 @@ import edu.cornell.mannlib.vitro.webapp.visualization.collaborationutils.Collabo import edu.cornell.mannlib.vitro.webapp.visualization.collaborationutils.CollaboratorComparator; import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.Collaboration; import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.Collaborator; +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; public class CoAuthorshipGraphMLWriter { private StringBuilder coAuthorshipGraphMLContent; - private final String GRAPHML_HEADER = "\n" - + " \n\n"; - - private final String GRAPHML_FOOTER = ""; + private final String GRAPHML_NS = "http://graphml.graphdrawing.org/xmlns"; public CoAuthorshipGraphMLWriter(CollaborationData visVOContainer) { coAuthorshipGraphMLContent = createCoAuthorshipGraphMLContent(visVOContainer); } - private StringBuilder createCoAuthorshipGraphMLContent( - CollaborationData coAuthorshipData) { - + private StringBuilder createCoAuthorshipGraphMLContent(CollaborationData coAuthorshipData) { + StringBuilder graphMLContent = new StringBuilder(); - - graphMLContent.append(GRAPHML_HEADER); - - /* - * We are side-effecting "graphMLContent" object in this method since creating - * another String object to hold key definition data will be redundant & will - * not serve the purpose. - * */ - generateKeyDefinitionContent(coAuthorshipData, graphMLContent); - - /* - * Used to generate graph content. It will contain both the nodes & edge information. - * We are side-effecting "graphMLContent". - * */ - generateGraphContent(coAuthorshipData, graphMLContent); - - graphMLContent.append(GRAPHML_FOOTER); - + + try { + DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance(); + docFactory.setNamespaceAware(true); + DocumentBuilder docBuilder = docFactory.newDocumentBuilder(); + + // root elements + Document doc = docBuilder.newDocument(); + doc.setXmlVersion("1.0"); + Element rootElement = doc.createElementNS(GRAPHML_NS, "graphml"); + doc.appendChild(rootElement); + + /* + * We are side-effecting "graphMLContent" object in this method since creating + * another String object to hold key definition data will be redundant & will + * not serve the purpose. + * */ + generateKeyDefinitionContent(coAuthorshipData, rootElement); + + /* + * Used to generate graph content. It will contain both the nodes & edge information. + * We are side-effecting "graphMLContent". + * */ + generateGraphContent(coAuthorshipData, rootElement); + + DOMSource source = new DOMSource(doc); + TransformerFactory transFactory = TransformerFactory.newInstance(); + Transformer transformer = transFactory.newTransformer(); + transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); + transformer.setOutputProperty(OutputKeys.INDENT, "yes"); + + StringWriter writer = new StringWriter(); + StreamResult result = new StreamResult(writer); + transformer.transform(source, result); + + graphMLContent.append(writer.toString()); + } catch (TransformerConfigurationException e) { + throw new IllegalStateException("XML error generating GraphML", e); + } catch (TransformerException e) { + throw new IllegalStateException("XML error generating GraphML", e); + } catch (ParserConfigurationException e) { + throw new IllegalStateException("XML error generating GraphML", e); + } + return graphMLContent; } @@ -62,119 +96,110 @@ public class CoAuthorshipGraphMLWriter { return coAuthorshipGraphMLContent; } - private void generateGraphContent(CollaborationData coAuthorshipData, - StringBuilder graphMLContent) { + private void generateGraphContent(CollaborationData coAuthorshipData, Element rootElement) { + Document doc = rootElement.getOwnerDocument(); - graphMLContent.append("\n\n"); - - if (coAuthorshipData.getCollaborators() != null - && coAuthorshipData.getCollaborators().size() > 0) { - generateNodeSectionContent(coAuthorshipData, graphMLContent); + Element graph = doc.createElementNS(GRAPHML_NS, "graph"); + graph.setAttribute("edgedefault", "undirected"); + rootElement.appendChild(graph); + + if (coAuthorshipData.getCollaborators() != null && coAuthorshipData.getCollaborators().size() > 0) { + generateNodeSectionContent(coAuthorshipData, graph); } - if (coAuthorshipData.getCollaborations() != null - && coAuthorshipData.getCollaborations().size() > 0) { - generateEdgeSectionContent(coAuthorshipData, graphMLContent); + if (coAuthorshipData.getCollaborations() != null && coAuthorshipData.getCollaborations().size() > 0) { + generateEdgeSectionContent(coAuthorshipData, graph); } - - graphMLContent.append("\n"); } - private void generateEdgeSectionContent(CollaborationData coAuthorshipData, - StringBuilder graphMLContent) { - - graphMLContent.append("\n"); - - Set edges = coAuthorshipData.getCollaborations(); - + private void generateEdgeSectionContent(CollaborationData coAuthorshipData, Element graphElement) { + Document doc = graphElement.getOwnerDocument(); + + graphElement.appendChild(doc.createComment("edges")); + + Set edges = coAuthorshipData.getCollaborations(); List orderedEdges = new ArrayList(edges); - Collections.sort(orderedEdges, new CollaborationComparator()); for (Collaboration currentEdge : orderedEdges) { - /* * This method actually creates the XML code for a single Collaboration. * "graphMLContent" is being side-effected. * */ - getEdgeContent(graphMLContent, currentEdge); + getEdgeContent(graphElement, currentEdge); } } - private void getEdgeContent(StringBuilder graphMLContent, Collaboration currentEdge) { - - graphMLContent.append("\n"); - - graphMLContent.append("\t" - + currentEdge.getSourceCollaborator().getCollaboratorName() - + "\n"); - - graphMLContent.append("\t" - + currentEdge.getTargetCollaborator().getCollaboratorName() - + "\n"); - - graphMLContent.append("\t" - + currentEdge.getNumOfCollaborations() - + "\n"); - + private void getEdgeContent(Element graphElement, Collaboration currentEdge) { + Document doc = graphElement.getOwnerDocument(); + + Element edge = doc.createElementNS(GRAPHML_NS, "edge"); + edge.setAttribute("id", String.valueOf(currentEdge.getCollaborationID())); + edge.setAttribute("source", String.valueOf(currentEdge.getSourceCollaborator().getCollaboratorID())); + edge.setAttribute("target", String.valueOf(currentEdge.getTargetCollaborator().getCollaboratorID())); + graphElement.appendChild(edge); + + Element collaborator1 = doc.createElementNS(GRAPHML_NS, "data"); + collaborator1.setAttribute("key", "collaborator1"); + collaborator1.setTextContent(currentEdge.getSourceCollaborator().getCollaboratorName()); + edge.appendChild(collaborator1); + + Element collaborator2 = doc.createElementNS(GRAPHML_NS, "data"); + collaborator2.setAttribute("key", "collaborator2"); + collaborator2.setTextContent(currentEdge.getTargetCollaborator().getCollaboratorName()); + edge.appendChild(collaborator2); + + Element works = doc.createElementNS(GRAPHML_NS, "data"); + works.setAttribute("key", "number_of_coauthored_works"); + works.setTextContent(String.valueOf(currentEdge.getNumOfCollaborations())); + edge.appendChild(works); + if (currentEdge.getEarliestCollaborationYearCount() != null) { - /* * There is no clean way of getting the map contents in java even though * we are sure to have only one entry on the map. So using the for loop. * */ - for (Map.Entry publicationInfo - : currentEdge.getEarliestCollaborationYearCount().entrySet()) { - - graphMLContent.append("\t" - + publicationInfo.getKey() - + "\n"); + for (Map.Entry publicationInfo : currentEdge.getEarliestCollaborationYearCount().entrySet()) { - graphMLContent.append("\t" - + publicationInfo.getValue() - + "\n"); + Element earliest = doc.createElementNS(GRAPHML_NS, "data"); + earliest.setAttribute("key", "earliest_collaboration"); + earliest.setTextContent(publicationInfo.getKey()); + edge.appendChild(earliest); + + Element earliestCount = doc.createElementNS(GRAPHML_NS, "data"); + earliestCount.setAttribute("key", "num_earliest_collaboration"); + earliestCount.setTextContent(publicationInfo.getValue().toString()); + edge.appendChild(earliestCount); } - } if (currentEdge.getLatestCollaborationYearCount() != null) { - - for (Map.Entry publicationInfo - : currentEdge.getLatestCollaborationYearCount().entrySet()) { - - graphMLContent.append("\t" - + publicationInfo.getKey() - + "\n"); + for (Map.Entry publicationInfo : currentEdge.getLatestCollaborationYearCount().entrySet()) { + Element latest = doc.createElementNS(GRAPHML_NS, "data"); + latest.setAttribute("key", "latest_collaboration"); + latest.setTextContent(publicationInfo.getKey()); + edge.appendChild(latest); - graphMLContent.append("\t" - + publicationInfo.getValue() - + "\n"); + Element latestCount = doc.createElementNS(GRAPHML_NS, "data"); + latestCount.setAttribute("key", "num_latest_collaboration"); + latestCount.setTextContent(publicationInfo.getValue().toString()); + edge.appendChild(latestCount); } - } if (currentEdge.getUnknownCollaborationYearCount() != null) { - - graphMLContent.append("\t" - + currentEdge.getUnknownCollaborationYearCount() - + "\n"); - + Element unknown = doc.createElementNS(GRAPHML_NS, "data"); + unknown.setAttribute("key", "num_unknown_collaboration"); + unknown.setTextContent(String.valueOf(currentEdge.getUnknownCollaborationYearCount())); + edge.appendChild(unknown); } - - graphMLContent.append("\n"); } - private void generateNodeSectionContent(CollaborationData coAuthorshipData, - StringBuilder graphMLContent) { - - graphMLContent.append("\n"); - + private void generateNodeSectionContent(CollaborationData coAuthorshipData, Element graphElement) { + Document doc = graphElement.getOwnerDocument(); + + graphElement.appendChild(doc.createComment("nodes")); + Collaborator egoNode = coAuthorshipData.getEgoCollaborator(); Set authorNodes = coAuthorshipData.getCollaborators(); @@ -184,142 +209,130 @@ public class CoAuthorshipGraphMLWriter { * of the co-author vis. Ego should always come first. * * */ - getNodeContent(graphMLContent, egoNode); + getNodeContent(graphElement, egoNode); List orderedAuthorNodes = new ArrayList(authorNodes); orderedAuthorNodes.remove(egoNode); Collections.sort(orderedAuthorNodes, new CollaboratorComparator()); - for (Collaborator currNode : orderedAuthorNodes) { - /* * We have already printed the Ego Collaborator info. * */ if (currNode != egoNode) { - - getNodeContent(graphMLContent, currNode); - + getNodeContent(graphElement, currNode); } - } } - private void getNodeContent(StringBuilder graphMLContent, Collaborator node) { + private void getNodeContent(Element graphElement, Collaborator collaborator) { + Document doc = graphElement.getOwnerDocument(); ParamMap individualProfileURLParams = - new ParamMap(VisualizationFrameworkConstants.INDIVIDUAL_URI_KEY, - node.getCollaboratorURI()); + new ParamMap(VisualizationFrameworkConstants.INDIVIDUAL_URI_KEY, collaborator.getCollaboratorURI()); + + String profileURL = UrlBuilder.getUrl(VisualizationFrameworkConstants.INDIVIDUAL_URL_PREFIX, individualProfileURLParams); + + Element node = doc.createElementNS(GRAPHML_NS, "node"); + node.setAttribute("id", String.valueOf(collaborator.getCollaboratorID())); + graphElement.appendChild(node); + + Element url = doc.createElementNS(GRAPHML_NS, "data"); + url.setAttribute("key", "url"); + url.setTextContent(collaborator.getCollaboratorURI()); + node.appendChild(url); + + Element label = doc.createElementNS(GRAPHML_NS, "data"); + label.setAttribute("key", "label"); + label.setTextContent(collaborator.getCollaboratorName()); + node.appendChild(label); - String profileURL = UrlBuilder.getUrl(VisualizationFrameworkConstants.INDIVIDUAL_URL_PREFIX, - individualProfileURLParams); - - graphMLContent.append("\n"); - graphMLContent.append("\t" + node.getCollaboratorURI() + "\n"); - graphMLContent.append("\t" + node.getCollaboratorName() + "\n"); - if (profileURL != null) { - graphMLContent.append("\t" + profileURL + "\n"); + Element profile = doc.createElementNS(GRAPHML_NS, "data"); + profile.setAttribute("key", "profile_url"); + profile.setTextContent(profileURL); + node.appendChild(profile); } - - graphMLContent.append("\t" - + node.getNumOfActivities() - + "\n"); - - if (node.getEarliestActivityYearCount() != null) { - + Element works = doc.createElementNS(GRAPHML_NS, "data"); + works.setAttribute("key", "number_of_authored_works"); + works.setTextContent(String.valueOf(collaborator.getNumOfActivities())); + node.appendChild(works); + + if (collaborator.getEarliestActivityYearCount() != null) { /* * There is no clean way of getting the map contents in java even though * we are sure to have only one entry on the map. So using the for loop. * I am feeling dirty just about now. * */ - for (Map.Entry publicationInfo - : node.getEarliestActivityYearCount().entrySet()) { - - graphMLContent.append("\t" - + publicationInfo.getKey() - + "\n"); + for (Map.Entry publicationInfo : collaborator.getEarliestActivityYearCount().entrySet()) { + Element earliest = doc.createElementNS(GRAPHML_NS, "data"); + earliest.setAttribute("key", "earliest_publication"); + earliest.setTextContent(publicationInfo.getKey()); + node.appendChild(earliest); - graphMLContent.append("\t" - + publicationInfo.getValue() - + "\n"); + Element earliestCount = doc.createElementNS(GRAPHML_NS, "data"); + earliestCount.setAttribute("key", "num_earliest_publication"); + earliestCount.setTextContent(publicationInfo.getValue().toString()); + node.appendChild(earliestCount); } - } - if (node.getLatestActivityYearCount() != null) { - - for (Map.Entry publicationInfo - : node.getLatestActivityYearCount().entrySet()) { - - graphMLContent.append("\t" - + publicationInfo.getKey() - + "\n"); + if (collaborator.getLatestActivityYearCount() != null) { + for (Map.Entry publicationInfo : collaborator.getLatestActivityYearCount().entrySet()) { + Element latest = doc.createElementNS(GRAPHML_NS, "data"); + latest.setAttribute("key", "latest_publication"); + latest.setTextContent(publicationInfo.getKey()); + node.appendChild(latest); - graphMLContent.append("\t" - + publicationInfo.getValue() - + "\n"); + Element latestCount = doc.createElementNS(GRAPHML_NS, "data"); + latestCount.setAttribute("key", "num_latest_publication"); + latestCount.setTextContent(publicationInfo.getValue().toString()); + node.appendChild(latestCount); } - } - if (node.getUnknownActivityYearCount() != null) { - - graphMLContent.append("\t" - + node.getUnknownActivityYearCount() - + "\n"); - + if (collaborator.getUnknownActivityYearCount() != null) { + Element unknown = doc.createElementNS(GRAPHML_NS, "data"); + unknown.setAttribute("key", "num_unknown_publication"); + unknown.setTextContent(String.valueOf(collaborator.getUnknownActivityYearCount())); + node.appendChild(unknown); } - - graphMLContent.append("\n"); } - private void generateKeyDefinitionContent(CollaborationData visVOContainer, - StringBuilder graphMLContent) { - + private void generateKeyDefinitionContent(CollaborationData visVOContainer, Element rootElement) { /* * Generate the key definition content for node. * */ - getKeyDefinitionFromSchema(visVOContainer.getNodeSchema(), graphMLContent); + getKeyDefinitionFromSchema(visVOContainer.getNodeSchema(), rootElement); /* * Generate the key definition content for edge. * */ - getKeyDefinitionFromSchema(visVOContainer.getEdgeSchema(), graphMLContent); + getKeyDefinitionFromSchema(visVOContainer.getEdgeSchema(), rootElement); } - private void getKeyDefinitionFromSchema(Set> schema, - StringBuilder graphMLContent) { - - for (Map currentNodeSchemaAttribute : schema) { - - graphMLContent.append("\n currentAttributeKey - : currentNodeSchemaAttribute.entrySet()) { - - graphMLContent.append(currentAttributeKey.getKey() - + "=\"" + currentAttributeKey.getValue() - + "\" "); + private void getKeyDefinitionFromSchema(Set> schema, Element rootElement) { + Document doc = rootElement.getOwnerDocument(); + for (Map currentNodeSchemaAttribute : schema) { + Element key = doc.createElementNS(GRAPHML_NS, "key"); + + for (Map.Entry currentAttributeKey : currentNodeSchemaAttribute.entrySet()) { + key.setAttribute(currentAttributeKey.getKey(), currentAttributeKey.getValue()); } if (currentNodeSchemaAttribute.containsKey("default")) { - - graphMLContent.append(">\n"); - graphMLContent.append(""); - graphMLContent.append(currentNodeSchemaAttribute.get("default")); - graphMLContent.append("\n"); - graphMLContent.append("\n"); - - } else { - graphMLContent.append("/>\n"); + Element def = doc.createElementNS(GRAPHML_NS, "default"); + def.setTextContent(currentNodeSchemaAttribute.get("default")); + key.appendChild(def); } + + rootElement.appendChild(key); } } } diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/visualization/coprincipalinvestigator/CoPIGraphMLWriter.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/visualization/coprincipalinvestigator/CoPIGraphMLWriter.java index 52309bc6..b5765e71 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/visualization/coprincipalinvestigator/CoPIGraphMLWriter.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/visualization/coprincipalinvestigator/CoPIGraphMLWriter.java @@ -2,6 +2,7 @@ package edu.cornell.mannlib.vitro.webapp.visualization.coprincipalinvestigator; +import java.io.StringWriter; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -16,47 +17,80 @@ import edu.cornell.mannlib.vitro.webapp.visualization.collaborationutils.Collabo import edu.cornell.mannlib.vitro.webapp.visualization.collaborationutils.CollaboratorComparator; import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.Collaboration; import edu.cornell.mannlib.vitro.webapp.visualization.valueobjects.Collaborator; +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; + /** * @author bkoniden * Deepak Konidena */ public class CoPIGraphMLWriter { - + private StringBuilder coPIGraphMLContent; - - private final String GRAPHML_HEADER = "\n" - + " \n\n"; - - private final String GRAPHML_FOOTER = ""; - + + private final String GRAPHML_NS = "http://graphml.graphdrawing.org/xmlns"; + public CoPIGraphMLWriter(CollaborationData coPIData) { coPIGraphMLContent = createCoPIGraphMLContent(coPIData); } private StringBuilder createCoPIGraphMLContent(CollaborationData coPIData) { - StringBuilder graphMLContent = new StringBuilder(); - - graphMLContent.append(GRAPHML_HEADER); - - /* - * We are side-effecting "graphMLContent" object in this method since creating - * another String object to hold key definition data will be redundant & will - * not serve the purpose. - * */ - generateKeyDefinitionContent(coPIData, graphMLContent); - - /* - * Used to generate graph content. It will contain both the nodes & edge information. - * We are side-effecting "graphMLContent". - * */ - generateGraphContent(coPIData, graphMLContent); - - graphMLContent.append(GRAPHML_FOOTER); - + + try { + DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance(); + docFactory.setNamespaceAware(true); + DocumentBuilder docBuilder = docFactory.newDocumentBuilder(); + + // root elements + Document doc = docBuilder.newDocument(); + doc.setXmlVersion("1.0"); + Element rootElement = doc.createElementNS(GRAPHML_NS, "graphml"); + doc.appendChild(rootElement); + + /* + * We are side-effecting "graphMLContent" object in this method since creating + * another String object to hold key definition data will be redundant & will + * not serve the purpose. + * */ + generateKeyDefinitionContent(coPIData, rootElement); + + /* + * Used to generate graph content. It will contain both the nodes & edge information. + * We are side-effecting "graphMLContent". + * */ + generateGraphContent(coPIData, rootElement); + + DOMSource source = new DOMSource(doc); + TransformerFactory transFactory = TransformerFactory.newInstance(); + Transformer transformer = transFactory.newTransformer(); + transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); + transformer.setOutputProperty(OutputKeys.INDENT, "yes"); + + StringWriter writer = new StringWriter(); + StreamResult result = new StreamResult(writer); + transformer.transform(source, result); + + graphMLContent.append(writer.toString()); + } catch (TransformerConfigurationException e) { + throw new IllegalStateException("XML error generating GraphML", e); + } catch (TransformerException e) { + throw new IllegalStateException("XML error generating GraphML", e); + } catch (ParserConfigurationException e) { + throw new IllegalStateException("XML error generating GraphML", e); + } + return graphMLContent; } @@ -64,118 +98,112 @@ public class CoPIGraphMLWriter { return coPIGraphMLContent; } - private void generateGraphContent(CollaborationData coPIData, - StringBuilder graphMLContent) { - - graphMLContent.append("\n\n"); - + private void generateGraphContent(CollaborationData coPIData, Element rootElement) { + Document doc = rootElement.getOwnerDocument(); + + Element graph = doc.createElementNS(GRAPHML_NS, "graph"); + graph.setAttribute("edgedefault", "undirected"); + rootElement.appendChild(graph); + if (coPIData.getCollaborators() != null & coPIData.getCollaborators().size() > 0) { - generateNodeSectionContent(coPIData, graphMLContent); + generateNodeSectionContent(coPIData, graph); } if (coPIData.getCollaborations() != null & coPIData.getCollaborations().size() > 0) { - generateEdgeSectionContent(coPIData, graphMLContent); + generateEdgeSectionContent(coPIData, graph); } - - graphMLContent.append("\n"); } - private void generateEdgeSectionContent(CollaborationData coPIData, - StringBuilder graphMLContent) { - - graphMLContent.append("\n"); + private void generateEdgeSectionContent(CollaborationData coPIData, Element graphElement) { + Document doc = graphElement.getOwnerDocument(); + + graphElement.appendChild(doc.createComment("edges")); Set edges = coPIData.getCollaborations(); - List orderedEdges = new ArrayList(edges); - Collections.sort(orderedEdges, new CollaborationComparator()); for (Collaboration currentEdge : orderedEdges) { - /* * This method actually creates the XML code for a single edge. "graphMLContent" * is being side-effected. * */ - getEdgeContent(graphMLContent, currentEdge); + getEdgeContent(graphElement, currentEdge); } } - private void getEdgeContent(StringBuilder graphMLContent, Collaboration currentEdge) { - - graphMLContent.append("\n"); - - graphMLContent.append("\t" - + currentEdge.getSourceCollaborator().getCollaboratorName() - + "\n"); - - graphMLContent.append("\t" - + currentEdge.getTargetCollaborator().getCollaboratorName() - + "\n"); - - graphMLContent.append("\t" - + currentEdge.getNumOfCollaborations() - + "\n"); - + private void getEdgeContent(Element graphElement, Collaboration currentEdge) { + Document doc = graphElement.getOwnerDocument(); + + Element edge = doc.createElementNS(GRAPHML_NS, "edge"); + edge.setAttribute("id", String.valueOf(currentEdge.getCollaborationID())); + edge.setAttribute("source", String.valueOf(currentEdge.getSourceCollaborator().getCollaboratorID())); + edge.setAttribute("target", String.valueOf(currentEdge.getTargetCollaborator().getCollaboratorID())); + graphElement.appendChild(edge); + + Element collaborator1 = doc.createElementNS(GRAPHML_NS, "data"); + collaborator1.setAttribute("key", "collaborator1"); + collaborator1.setTextContent(currentEdge.getSourceCollaborator().getCollaboratorName()); + edge.appendChild(collaborator1); + + Element collaborator2 = doc.createElementNS(GRAPHML_NS, "data"); + collaborator2.setAttribute("key", "collaborator2"); + collaborator2.setTextContent(currentEdge.getTargetCollaborator().getCollaboratorName()); + edge.appendChild(collaborator2); + + Element works = doc.createElementNS(GRAPHML_NS, "data"); + works.setAttribute("key", "number_of_coinvestigated_grants"); + works.setTextContent(String.valueOf(currentEdge.getNumOfCollaborations())); + edge.appendChild(works); + if (currentEdge.getEarliestCollaborationYearCount() != null) { - /* * There is no clean way of getting the map contents in java even though * we are sure to have only one entry on the map. So using the for loop. * */ - for (Map.Entry publicationInfo - : currentEdge.getEarliestCollaborationYearCount().entrySet()) { - - graphMLContent.append("\t" - + publicationInfo.getKey() - + "\n"); + for (Map.Entry publicationInfo : currentEdge.getEarliestCollaborationYearCount().entrySet()) { - graphMLContent.append("\t" - + publicationInfo.getValue() - + "\n"); + Element earliest = doc.createElementNS(GRAPHML_NS, "data"); + earliest.setAttribute("key", "earliest_collaboration"); + earliest.setTextContent(publicationInfo.getKey()); + edge.appendChild(earliest); + + Element earliestCount = doc.createElementNS(GRAPHML_NS, "data"); + earliestCount.setAttribute("key", "num_earliest_collaboration"); + earliestCount.setTextContent(publicationInfo.getValue().toString()); + edge.appendChild(earliestCount); } } if (currentEdge.getLatestCollaborationYearCount() != null) { - - for (Map.Entry publicationInfo - : currentEdge.getLatestCollaborationYearCount().entrySet()) { - - graphMLContent.append("\t" - + publicationInfo.getKey() - + "\n"); + for (Map.Entry publicationInfo : currentEdge.getLatestCollaborationYearCount().entrySet()) { + Element latest = doc.createElementNS(GRAPHML_NS, "data"); + latest.setAttribute("key", "latest_collaboration"); + latest.setTextContent(publicationInfo.getKey()); + edge.appendChild(latest); - graphMLContent.append("\t" - + publicationInfo.getValue() - + "\n"); + Element latestCount = doc.createElementNS(GRAPHML_NS, "data"); + latestCount.setAttribute("key", "num_latest_collaboration"); + latestCount.setTextContent(publicationInfo.getValue().toString()); + edge.appendChild(latestCount); } } if (currentEdge.getUnknownCollaborationYearCount() != null) { - - graphMLContent.append("\t" - + currentEdge.getUnknownCollaborationYearCount() - + "\n"); - + Element unknown = doc.createElementNS(GRAPHML_NS, "data"); + unknown.setAttribute("key", "num_unknown_collaboration"); + unknown.setTextContent(String.valueOf(currentEdge.getUnknownCollaborationYearCount())); + edge.appendChild(unknown); } - - graphMLContent.append("\n"); } - - private void generateNodeSectionContent(CollaborationData coPIData, - StringBuilder graphMLContent) { - - graphMLContent.append("\n"); - + private void generateNodeSectionContent(CollaborationData coPIData, Element graphElement) { + Document doc = graphElement.getOwnerDocument(); + + graphElement.appendChild(doc.createComment("nodes")); + Collaborator egoNode = coPIData.getEgoCollaborator(); Set piNodes = coPIData.getCollaborators(); @@ -185,7 +213,7 @@ public class CoPIGraphMLWriter { * of the co-pi vis. Ego should always come first. * * */ - getNodeContent(graphMLContent, egoNode); + getNodeContent(graphElement, egoNode); List orderedPINodes = new ArrayList(piNodes); orderedPINodes.remove(egoNode); @@ -194,131 +222,119 @@ public class CoPIGraphMLWriter { for (Collaborator currNode : orderedPINodes) { - /* * We have already printed the Ego Node info. * */ if (currNode != egoNode) { - - getNodeContent(graphMLContent, currNode); - + getNodeContent(graphElement, currNode); } - } - } - private void getNodeContent(StringBuilder graphMLContent, Collaborator node) { - - ParamMap individualProfileURLParams = new ParamMap( - VisualizationFrameworkConstants.INDIVIDUAL_URI_KEY, - node.getCollaboratorURI()); + private void getNodeContent(Element graphElement, Collaborator collaborator) { + Document doc = graphElement.getOwnerDocument(); - String profileURL = UrlBuilder.getUrl(VisualizationFrameworkConstants.INDIVIDUAL_URL_PREFIX, - individualProfileURLParams); - - graphMLContent.append("\n"); - graphMLContent.append("\t" + node.getCollaboratorURI() + "\n"); - graphMLContent.append("\t" + node.getCollaboratorName() + "\n"); + ParamMap individualProfileURLParams = new ParamMap( + VisualizationFrameworkConstants.INDIVIDUAL_URI_KEY, collaborator.getCollaboratorURI()); + + String profileURL = UrlBuilder.getUrl(VisualizationFrameworkConstants.INDIVIDUAL_URL_PREFIX, individualProfileURLParams); + + Element node = doc.createElementNS(GRAPHML_NS, "node"); + node.setAttribute("id", String.valueOf(collaborator.getCollaboratorID())); + graphElement.appendChild(node); + + Element url = doc.createElementNS(GRAPHML_NS, "data"); + url.setAttribute("key", "url"); + url.setTextContent(collaborator.getCollaboratorURI()); + node.appendChild(url); + + Element label = doc.createElementNS(GRAPHML_NS, "data"); + label.setAttribute("key", "label"); + label.setTextContent(collaborator.getCollaboratorName()); + node.appendChild(label); if (profileURL != null) { - graphMLContent.append("\t" + profileURL + "\n"); + Element profile = doc.createElementNS(GRAPHML_NS, "data"); + profile.setAttribute("key", "profile_url"); + profile.setTextContent(profileURL); + node.appendChild(profile); } - - - graphMLContent.append("\t" - + node.getNumOfActivities() - + "\n"); - - if (node.getEarliestActivityYearCount() != null) { - + + Element works = doc.createElementNS(GRAPHML_NS, "data"); + works.setAttribute("key", "number_of_investigated_grants"); + works.setTextContent(String.valueOf(collaborator.getNumOfActivities())); + node.appendChild(works); + + if (collaborator.getEarliestActivityYearCount() != null) { /* * There is no clean way of getting the map contents in java even though * we are sure to have only one entry on the map. So using the for loop. * I am feeling dirty just about now. * */ - for (Map.Entry publicationInfo - : node.getEarliestActivityYearCount().entrySet()) { - - graphMLContent.append("\t" - + publicationInfo.getKey() - + "\n"); + for (Map.Entry publicationInfo : collaborator.getEarliestActivityYearCount().entrySet()) { + Element earliest = doc.createElementNS(GRAPHML_NS, "data"); + earliest.setAttribute("key", "earliest_grant"); + earliest.setTextContent(publicationInfo.getKey()); + node.appendChild(earliest); - graphMLContent.append("\t" - + publicationInfo.getValue() - + "\n"); + Element earliestCount = doc.createElementNS(GRAPHML_NS, "data"); + earliestCount.setAttribute("key", "num_earliest_grant"); + earliestCount.setTextContent(publicationInfo.getValue().toString()); + node.appendChild(earliestCount); } - } - if (node.getLatestActivityYearCount() != null) { - - for (Map.Entry publicationInfo - : node.getLatestActivityYearCount().entrySet()) { - - graphMLContent.append("\t" - + publicationInfo.getKey() - + "\n"); + if (collaborator.getLatestActivityYearCount() != null) { + for (Map.Entry publicationInfo : collaborator.getLatestActivityYearCount().entrySet()) { + Element latest = doc.createElementNS(GRAPHML_NS, "data"); + latest.setAttribute("key", "latest_grant"); + latest.setTextContent(publicationInfo.getKey()); + node.appendChild(latest); - graphMLContent.append("\t" - + publicationInfo.getValue() - + "\n"); + Element latestCount = doc.createElementNS(GRAPHML_NS, "data"); + latestCount.setAttribute("key", "num_latest_grant"); + latestCount.setTextContent(publicationInfo.getValue().toString()); + node.appendChild(latestCount); } - } - if (node.getUnknownActivityYearCount() != null) { - - graphMLContent.append("\t" - + node.getUnknownActivityYearCount() - + "\n"); - + if (collaborator.getUnknownActivityYearCount() != null) { + Element unknown = doc.createElementNS(GRAPHML_NS, "data"); + unknown.setAttribute("key", "num_unknown_grant"); + unknown.setTextContent(String.valueOf(collaborator.getUnknownActivityYearCount())); + node.appendChild(unknown); } - - graphMLContent.append("\n"); } - private void generateKeyDefinitionContent(CollaborationData coPIData, - StringBuilder graphMLContent) { + private void generateKeyDefinitionContent(CollaborationData coPIData, Element rootElement) { /* * Generate the key definition content for node. * */ - getKeyDefinitionFromSchema(coPIData.getNodeSchema(), graphMLContent); + getKeyDefinitionFromSchema(coPIData.getNodeSchema(), rootElement); /* * Generate the key definition content for edge. * */ - getKeyDefinitionFromSchema(coPIData.getEdgeSchema(), graphMLContent); + getKeyDefinitionFromSchema(coPIData.getEdgeSchema(), rootElement); } - private void getKeyDefinitionFromSchema(Set> schema, - StringBuilder graphMLContent) { - - for (Map currentNodeSchemaAttribute : schema) { - - graphMLContent.append("\n currentAttributeKey - : currentNodeSchemaAttribute.entrySet()) { - - graphMLContent.append(currentAttributeKey.getKey() - + "=\"" + currentAttributeKey.getValue() - + "\" "); + private void getKeyDefinitionFromSchema(Set> schema, Element rootElement) { + Document doc = rootElement.getOwnerDocument(); + for (Map currentNodeSchemaAttribute : schema) { + Element key = doc.createElementNS(GRAPHML_NS, "key"); + + for (Map.Entry currentAttributeKey : currentNodeSchemaAttribute.entrySet()) { + key.setAttribute(currentAttributeKey.getKey(), currentAttributeKey.getValue()); } if (currentNodeSchemaAttribute.containsKey("default")) { - - graphMLContent.append(">\n"); - graphMLContent.append(""); - graphMLContent.append(currentNodeSchemaAttribute.get("default")); - graphMLContent.append("\n"); - graphMLContent.append("\n"); - - } else { - graphMLContent.append("/>\n"); + Element def = doc.createElementNS(GRAPHML_NS, "default"); + def.setTextContent(currentNodeSchemaAttribute.get("default")); + key.appendChild(def); } + + rootElement.appendChild(key); } } - }