package edu.asu.spring.quadriga.service.network.transform.impl; import java.io.IOException; import java.io.StringWriter; import java.util.ArrayList; import java.util.List; import javax.annotation.PostConstruct; import org.apache.velocity.Template; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.VelocityEngine; import org.apache.velocity.exception.MethodInvocationException; import org.apache.velocity.exception.ParseErrorException; import org.apache.velocity.exception.ResourceNotFoundException; import org.apache.velocity.runtime.RuntimeConstants; import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; import org.springframework.stereotype.Service; import edu.asu.spring.quadriga.conceptpower.IConceptpowerConnector; import edu.asu.spring.quadriga.domain.impl.ConceptpowerReply; import edu.asu.spring.quadriga.exceptions.QuadrigaGeneratorException; /** * This class generates the output for transformed networks using Apache * velocity. * */ @Service public class Generator { @Autowired private IConceptpowerConnector connector; private VelocityEngine engine; @PostConstruct public void initVelocityEngine() throws QuadrigaGeneratorException { engine = new VelocityEngine(); engine.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath,file"); engine.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName()); engine.setProperty( RuntimeConstants.RUNTIME_LOG_LOGSYSTEM_CLASS, "org.apache.velocity.runtime.log.Log4JLogChute" ); engine.setProperty("runtime.log.logsystem.log4j.logger","velocity"); try { engine.init(); } catch (Exception e) { throw new QuadrigaGeneratorException(e); } } public String generateText(List<List<TransformNode>> listOfNodeList, String chosenTemplate, boolean isMergeDuplicateNodes) throws QuadrigaGeneratorException { Resource templateRes = new ClassPathResource("transformation/xgmml-time.vm"); String templatePath; try { templatePath = templateRes.getFile().getAbsolutePath(); } catch (IOException e1) { throw new QuadrigaGeneratorException(e1); } Template template = null; /* * if User selects a different template, override default template with * chosen template. */ if (chosenTemplate != null || ("").equalsIgnoreCase(chosenTemplate)) templatePath = chosenTemplate; List<TransformNode> nodes = new ArrayList<TransformNode>(); List<String> nodeIds = new ArrayList<String>(); List<TransformLink> links = new ArrayList<TransformLink>(); /* * We need to create a list of nodes with unique concepts(merge nodes) * and gather all links associated to all nodes */ if (listOfNodeList != null && !listOfNodeList.isEmpty()) for (List<TransformNode> nodeList : listOfNodeList) for (TransformNode node : nodeList) createList(node, nodes, links, nodeIds, isMergeDuplicateNodes); /* * We need to rearrange links to point to the concept they are related * to, as redundant concept nodes are merged. */ if(isMergeDuplicateNodes) { realignLinks(nodes, links); } try { template = engine.getTemplate("transformation/xgmml-time.vm"); } catch (ResourceNotFoundException e) { throw new QuadrigaGeneratorException(e); } catch (ParseErrorException e) { throw new QuadrigaGeneratorException(e); } catch (Exception e) { throw new QuadrigaGeneratorException(e); } VelocityContext context = new VelocityContext(); context.put("nodes", nodes); context.put("links", links); StringWriter writer = new StringWriter(); if (template != null) { try { template.merge(context, writer); } catch (ResourceNotFoundException e) { throw new QuadrigaGeneratorException(e); } catch (ParseErrorException e) { throw new QuadrigaGeneratorException(e); } catch (MethodInvocationException e) { throw new QuadrigaGeneratorException(e); } catch (Exception e) { throw new QuadrigaGeneratorException(e); } } return writer.toString(); } /** * This method realigns link to point to the * relevant concept, as redundant concepts are merged to one node * per concept . * * @author Prajakta Samant * * @param nodes * @param links */ private void realignLinks(List<TransformNode> nodes, List<TransformLink> links) { if (links != null) { for (TransformLink link : links) { if (link.getSubject() != null) { for (TransformNode node : nodes) { if (link.getSubject().getConcept() != null && link.getSubject().getConcept() .equals(node.getConcept())) { link.setSubject(node); break; } } } if (link.getObject() != null) { for (TransformNode node : nodes) { if (link.getObject().getConcept() != null && link.getObject().getConcept() .equals(node.getConcept())) { link.setObject(node); break; } } } } } } /** * @author Prajakta Samant Create a list of nodes of unique concepts and * list of all links. * @param node * @param nodeList * @param links * @param existingIds */ protected void createList(TransformNode node, List<TransformNode> nodeList, List<TransformLink> links, List<String> existingIds, boolean mergeConcepts) { if (node != null) { /* * Add node to the list only if it has a new concept. We are * maintaining nodelist of unique concepts */ String id = node.getId(); if (mergeConcepts) id = node.getConcept(); if (!existingIds.contains(id)) { nodeList.add(node); existingIds.add(id); } /* * Add all links to the TransformLink list, even those of repeated * nodes. */ if (node.getLinks() != null && connector != null) { for (TransformLink link : node.getLinks()) { if (links.contains(link)) continue; if (link.getOccurTime() != null) { ConceptpowerReply concept = connector.getById(link .getOccurTime()); if(concept!=null) link.setOccurTime(concept.getConceptEntry().get(0).getLemma()); } // else // link.setOccurTime(""); if (link.getStartTime() != null) { ConceptpowerReply concept = connector.getById(link .getStartTime()); if(concept!=null) { link.setStartTime(concept.getConceptEntry().get(0).getLemma()); } } // else // link.setStartTime(""); if (link.getEndTime() != null) { ConceptpowerReply concept = connector.getById(link .getEndTime()); if(concept!=null) { link.setEndTime(concept.getConceptEntry().get(0).getLemma()); } } // else // link.setEndTime(""); if (link.getPlace() != null) { ConceptpowerReply concept = connector.getById(link .getPlace()); if(concept!=null) { link.setPlace(concept.getConceptEntry().get(0).getLemma()); } } // else // link.setPlace(""); links.add(link); createList(link.getObject(), nodeList, links, existingIds, mergeConcepts); } } } } }