All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.st.p2012.mind.adl.HTMLDocumentGenerator Maven / Gradle / Ivy

The newest version!
/**
   \file com/st/p2012/mind/adl/HTMLDocumentGenerator.java
   \brief The class encapsulating the HTML document generator template component.


   
   \n
   This file is part of the Platform 2012 program,
   a cooperation between STMicroelectronics and CEA.\n
   Redistribution of this file to outside parties is
   strictly prohibited without the written consent
   of the module owner indicated below.\n
   

   \par  Module owner: [email protected]


   \par  Copyright (C) 2009 STMicroelectronics

   \par  Authors: [email protected]

   \par  Id: $Id$
   \par  Date: $Date$
   \par  Revision: $Rev$

 */

package com.st.p2012.mind.adl;

import static com.st.p2012.mind.HTMLDocumentationHelper.getBindingAnchor;
import static com.st.p2012.mind.HTMLDocumentationHelper.getInterfaceAnchor;
import static com.st.p2012.mind.HTMLDocumentationHelper.getPathToRoot;
import static com.st.p2012.mind.HTMLDocumentationHelper.getSubComponentAnchor;
import static com.st.p2012.mind.HTMLDocumentationHelper.getAttributeAnchor;
import static com.st.p2012.mind.HTMLDocumentationHelper.getImplementationAnchor;
import static org.objectweb.fractal.adl.types.TypeInterfaceUtil.isClient;
import static org.objectweb.fractal.adl.types.TypeInterfaceUtil.isServer;
import static org.objectweb.fractal.mind.PathHelper.fullyQualifiedNameToPath;
import static org.objectweb.fractal.mind.adl.ast.ASTHelper.isComposite;
import static org.objectweb.fractal.mind.adl.ast.ASTHelper.isPrimitive;
import static org.objectweb.fractal.mind.adl.ast.ASTHelper.isType;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.antlr.stringtemplate.StringTemplate;
import org.antlr.stringtemplate.StringTemplateGroup;
import org.antlr.stringtemplate.language.DefaultTemplateLexer;
import org.objectweb.fractal.adl.ADLException;
import org.objectweb.fractal.adl.CompilerError;
import org.objectweb.fractal.adl.Definition;
import org.objectweb.fractal.adl.interfaces.Interface;
import org.objectweb.fractal.adl.interfaces.InterfaceContainer;
import org.objectweb.fractal.adl.types.TypeInterface;
import org.objectweb.fractal.cecilia.adl.file.SourceFileWriter;
import org.objectweb.fractal.mind.adl.AbstractSourceGenerator;
import org.objectweb.fractal.mind.adl.DefinitionSourceGenerator;
import org.objectweb.fractal.mind.adl.ast.ASTHelper;
import org.objectweb.fractal.mind.adl.ast.Attribute;
import org.objectweb.fractal.mind.adl.ast.AttributeContainer;
import org.objectweb.fractal.mind.adl.ast.Component;
import org.objectweb.fractal.mind.adl.ast.ComponentContainer;
import org.objectweb.fractal.mind.adl.ast.Data;
import org.objectweb.fractal.mind.adl.ast.DefinitionReference;
import org.objectweb.fractal.mind.adl.ast.Binding;
import org.objectweb.fractal.mind.adl.ast.BindingContainer;
import org.objectweb.fractal.mind.adl.ast.ImplementationContainer;
import org.objectweb.fractal.mind.adl.ast.Source;
import org.objectweb.fractal.mind.adl.generic.ast.FormalTypeParameter;
import org.objectweb.fractal.mind.adl.generic.ast.FormalTypeParameterContainer;
import org.objectweb.fractal.mind.adl.generic.ast.TypeArgument;
import org.objectweb.fractal.mind.adl.generic.ast.TypeArgumentContainer;
import org.objectweb.fractal.mind.io.IOErrors;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import com.st.p2012.mind.HTMLDocumentationHelper;
import com.st.p2012.mind.HTMLRenderer;
import com.st.p2012.mind.MindocConfig;
import com.st.p2012.mind.HTMLDocumentationHelper.SourceKind;
import com.st.p2012.mind.comments.CommentProcessor;

public class HTMLDocumentGenerator extends AbstractSourceGenerator
    implements
      DefinitionSourceGenerator {

  public String              pathToRoot;

  public HTMLDocumentGenerator() {
    super("st.definitions.documentation.Component");
  }

  public void visit(final Definition definition,
      final Map context) throws ADLException {
    pathToRoot = getPathToRoot(definition.getName());
    addDecorations(definition, (File)context.get("sourceDirectory"));
    final StringTemplate st = getInstanceOf("ComponentDocumentation");
    st.setAttribute("definition", definition);
    final Map> anchorMap = getAnchorMap(definition);
    st.setAttribute("anchors", anchorMap);
    st.setAttribute("sectionAnchors", getSectionAnchors(definition, anchorMap));
    st.setAttribute("links", getLinkMap(definition, (File)context.get("sourceDirectory")));
    st.setAttribute("pathToRoot", pathToRoot);


    CommentProcessor.process(definition);

    final File outputFile = outputFileLocatorItf.getCSourceOutputFile(
        getOutputFileName(definition), context);

    try {
      SourceFileWriter.writeToFile(outputFile, st.toString());
    } catch (final IOException e) {
      throw new CompilerError(IOErrors.WRITE_ERROR, e, outputFile
          .getAbsolutePath());
    }
  }

  private Map getSectionAnchors(final Definition definition,
      final Map> anchorMap) {
    final Map map = new HashMap();

    if(anchorMap.get("attr").size() != 0)
      map.put("attributes", HTMLDocumentationHelper.ATTRIBUTE_SECTION_ANCHOR);

    if (definition instanceof ImplementationContainer) {
      final ImplementationContainer implContainer = (ImplementationContainer)definition;
      final Data data = implContainer.getData();
      if(data != null && (data.getCCode() != null || data.getPath() != null))
        map.put("data", HTMLDocumentationHelper.DATA_SECTION_ANCHOR);
    }

    if(definition.astGetDecoration("clientInterfaces") != null)
      map.put("clientInterfaces", HTMLDocumentationHelper.CLIENT_INTERFACE_SECTION_ANCHOR);

    if(definition.astGetDecoration("serverInterfaces") != null)
      map.put("serverInterfaces", HTMLDocumentationHelper.SERVER_INTERFACE_SECTION_ANCHOR);

    if(anchorMap.get("cmp").size() != 0)
      map.put("components", HTMLDocumentationHelper.COMPONENT_SECTION_ANCHOR);

    if(anchorMap.get("bind").size() != 0)
      map.put("bindings", HTMLDocumentationHelper.BINDING_SECTION_ANCHOR);

    if(anchorMap.get("impl").size() != 0)
      map.put("implementations", HTMLDocumentationHelper.IMPLEMENTATION_SECTION_ANCHOR);

    return map;
  }

  private Map> getAnchorMap(
      final Definition definition) {
    final Map> superMap = new HashMap>();

    Map map = new HashMap();
    superMap.put("itf", map);
    if (definition instanceof InterfaceContainer) {
      final InterfaceContainer itfContainer = (InterfaceContainer) definition;
      for (final Interface itf : itfContainer.getInterfaces()) {
        map.put(itf.getName(), getInterfaceAnchor(itf.getName()));
      }
    }

    map = new HashMap();
    superMap.put("cmp", map);
    if (definition instanceof ComponentContainer) {
      final ComponentContainer cmpContainer = (ComponentContainer) definition;
      for (final Component cmp : cmpContainer.getComponents()) {
        map.put(cmp.getName(), getSubComponentAnchor(cmp.getName()));
      }
    }

    map = new HashMap();
    superMap.put("bind", map);
    if (definition instanceof BindingContainer) {
      final BindingContainer bndContainer = (BindingContainer) definition;
      for (final Binding binding : bndContainer.getBindings()) {
        map.put(binding.toString(), getBindingAnchor(
            binding.getFromComponent(), binding.getFromInterface(),
            binding.getToComponent(), binding.getToInterface()));

      }
    }

    map = new HashMap();
    superMap.put("attr", map);
    if (definition instanceof AttributeContainer) {
      final AttributeContainer attrContainer = (AttributeContainer) definition;
      for (final Attribute attr : attrContainer.getAttributes()) {
        map.put(attr.getName(), getAttributeAnchor(attr.getName()));
      }
    }

    map = new HashMap();
    superMap.put("impl", map);
    if (definition instanceof ImplementationContainer) {
      final ImplementationContainer implContainer = (ImplementationContainer) definition;
      for (final Source src : implContainer.getSources()) {
        map.put(src.toString(), getImplementationAnchor(src.getPath()));
      }
    }
    return superMap;
  }

  private Map> getLinkMap(
      final Definition definition, final File sourceDirectory) throws ADLException {
    final Map> superMap = new HashMap>();

    Map map = new HashMap();
    superMap.put("itf", map);
    if (definition instanceof InterfaceContainer) {
      final InterfaceContainer itfContainer = (InterfaceContainer) definition;
      for (final Interface itf : itfContainer.getInterfaces()) {
        if (itf instanceof TypeInterface) {
          final TypeInterface typeItf = (TypeInterface) itf;
          final String s = typeItf.getSignature();
          map.put(s, HTMLDocumentationHelper.getRelativePathToITF(definition.getName(), s, SourceKind.COMPONENT));

        }
      }
    }

    map = new HashMap();
    superMap.put("cmp", map);
    if (definition instanceof ComponentContainer) {
      final ComponentContainer cmpContainer = (ComponentContainer) definition;
      for (final Component cmp : cmpContainer.getComponents()) {
        String name = null;

        final DefinitionReference defRef = cmp.getDefinitionReference();
        if(defRef != null) {
          name = defRef.getName();
          if(defRef instanceof TypeArgumentContainer)
            addTypeArgumentLinks(definition, map, (TypeArgumentContainer) defRef);
        } else {
          final Definition def =  ASTHelper.getResolvedComponentDefinition(cmp, null, null);
          if(def != null) {
            name = def.getName();
          } else {
            continue;
          }
        }
        map.put(name, HTMLDocumentationHelper.getRelativePathToADL(definition.getName(), name, SourceKind.COMPONENT));
      }
    }

    if(definition.astGetDecoration("extends") != null) {
      final ExtendsDecoration extendsList = (ExtendsDecoration) definition.astGetDecoration("extends");
      for (final DefinitionReference defRef : extendsList.getExtends()) {
        addDefinitionReferenceLink(definition, map, defRef);
      }
    }

    map = new HashMap();
    superMap.put("impl", map);
    if (definition instanceof ImplementationContainer) {
      final ImplementationContainer implContainer = (ImplementationContainer) definition;
      for (final Source src : implContainer.getSources()) {
        map.put(src.toString(), getLinkForSource(src.getPath(), sourceDirectory));
      }
    }
    return superMap;
  }

  private void addDefinitionReferenceLink(final Definition definition,
      final Map map, final DefinitionReference definitionReference) {
    map.put(definitionReference.getName(), HTMLDocumentationHelper.getRelativePathToADL(definition.getName(), definitionReference.getName(), SourceKind.COMPONENT));
  }

  private void addTypeArgumentLinks(final Definition definition, final Map map, final TypeArgumentContainer typeArgumentContainer) {
    for (final TypeArgument typeArg : typeArgumentContainer.getTypeArguments()) {
      final DefinitionReference argDefRef = typeArg.getDefinitionReference();
      addDefinitionReferenceLink(definition, map, argDefRef);
      if(argDefRef instanceof TypeArgumentContainer) {
        addTypeArgumentLinks(definition, map, (TypeArgumentContainer)argDefRef);
      }
    }
  }

  private String getLinkForSource(String sourceFileName, final File sourceDirectory) {
    if(sourceDirectory == null)
      return sourceFileName;

    final String urlFormat = "%s%s?diff_format=h&roottype=svn&pathrev=%d&view=markup&root=%s";
    String sourceFileURL = null;
    String svnRoot = null;
    int revision = -1;

    if(sourceFileName.startsWith("/")) {
      sourceFileName = sourceFileName.substring(1);
    }

    final File sourceFile = new File(sourceDirectory, sourceFileName);
    sourceFileName = sourceFile.getAbsolutePath();

    try {
      final Process svnProcess = Runtime.getRuntime().exec("svn info --xml " + sourceFileName);

      if(svnProcess.waitFor() != 0) {
        final BufferedReader reader = new BufferedReader(new InputStreamReader(svnProcess.getErrorStream()));
        String line;
        while((line = reader.readLine()) != null) {
          System.out.println(line);
        }
        return sourceFileName;
      }

      final DocumentBuilder documentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
      final Document doc = documentBuilder.parse(svnProcess.getInputStream());


      NodeList nodeList = doc.getElementsByTagName("url");
      if(nodeList.getLength() >= 1) {
        sourceFileURL = nodeList.item(0).getTextContent();
      }

      nodeList = doc.getElementsByTagName("entry");
      if(nodeList.getLength() >= 1) {
        revision = Integer.parseInt(nodeList.item(0).getAttributes().getNamedItem("revision").getTextContent());
      }

      nodeList = doc.getElementsByTagName("root");
      if(nodeList.getLength() >= 1) {
        svnRoot = nodeList.item(0).getTextContent();
      }
    } catch (final IOException e) {
      return sourceFileName;
    } catch (final InterruptedException e) {
      return sourceFileName;
    } catch (final SAXException e) {
      return sourceFileName;
    } catch (final ParserConfigurationException e) {
      return sourceFileName;
    }

    if(sourceFileURL == null || svnRoot == null || revision == -1)
    {
      return sourceFileName;
    }

    if(sourceFileURL.startsWith(svnRoot)) {
      sourceFileName = sourceFileURL.substring(svnRoot.length());
    } else {
      return sourceFileName;
    }
    return String.format(urlFormat, MindocConfig.getSVNViewVCURL(), sourceFileName, revision, MindocConfig.getSVNProjectName());
  }

  private void addDecorations(final Definition definition, final File sourceDirectory) throws ADLException {
    setDefinitionKind(definition);
    HTMLDocumentationHelper.addAnnotationDecoration(definition);

    final List clientInterfaces = new LinkedList();
    final List serverInterfaces = new LinkedList();
    if (definition instanceof InterfaceContainer) {
      final InterfaceContainer itfContainer = (InterfaceContainer) definition;
      for (final Interface itf : itfContainer.getInterfaces()) {
        if (isClient(itf)) {
          clientInterfaces.add(itf);
        } else if (isServer(itf)) {
          serverInterfaces.add(itf);
        }
        HTMLDocumentationHelper.addAnnotationDecoration(itf);
      }

    }
    if (!clientInterfaces.isEmpty()) {
      definition.astSetDecoration("clientInterfaces", clientInterfaces);
    }
    if (!serverInterfaces.isEmpty()) {
      definition.astSetDecoration("serverInterfaces", serverInterfaces);
    }

    if (definition instanceof ImplementationContainer) {
      final ImplementationContainer implContainer = (ImplementationContainer)definition;
      final Data data = implContainer.getData();
      if(data != null) {
        HTMLDocumentationHelper.addAnnotationDecoration(data);
        if(data.getPath() != null) {
          data.astSetDecoration("link", getLinkForSource(data.getPath(), sourceDirectory));
        }
      }
      for (final Source source : implContainer.getSources()) {
        HTMLDocumentationHelper.addAnnotationDecoration(source);
      }

    }

    if (definition instanceof ComponentContainer) {
      final ComponentContainer componentCont = (ComponentContainer)definition;
      for (final Component comp : componentCont.getComponents()) {
        if(comp.getDefinitionReference() != null) {
          final DefinitionReference defRef = comp.getDefinitionReference();
          setDefinitionReferenceKind(defRef);
        } else {
          setDefinitionKind(ASTHelper.getResolvedComponentDefinition(comp, null, null));
        }
        HTMLDocumentationHelper.addAnnotationDecoration(comp);
      }
    }

    if (definition instanceof FormalTypeParameterContainer) {
      for (final FormalTypeParameter typeParam: ((FormalTypeParameterContainer)definition).getFormalTypeParameters()) {
        setDefinitionReferenceKind(typeParam.getDefinitionReference());
      }
    }

    if(definition.astGetDecoration("extends") != null) {
      final ExtendsDecoration extendsList = (ExtendsDecoration) definition.astGetDecoration("extends");
      for (final DefinitionReference defRef : extendsList.getExtends()) {
        setDefinitionReferenceKind(defRef);
      }
    }

    if(definition instanceof BindingContainer) {
      for (final Binding binding : ((BindingContainer)definition).getBindings()) {
        HTMLDocumentationHelper.addAnnotationDecoration(binding);
      }
    }

    if(definition instanceof AttributeContainer) {
      for(final Attribute attr: ((AttributeContainer) definition).getAttributes()) {
        HTMLDocumentationHelper.addAnnotationDecoration(attr);
        final String valueString = HTMLDocumentationHelper.getValueString(attr.getValue());
        if(valueString != null)
          attr.astSetDecoration("value", valueString);
      }
    }
  }

  private String setDefinitionKind(final Definition definition) {
    final String kind = getKind(definition);
    definition.astSetDecoration("kind", kind);
    return kind;
  }

  private void setDefinitionReferenceKind(final DefinitionReference definitionReference) throws ADLException {
    final Definition def = ASTHelper.getResolvedDefinition(definitionReference, null, null);
    final String kind = setDefinitionKind(def);
    definitionReference.astSetDecoration("kind", kind);
  }

  private String getKind(final Definition definition) {
    if (isType(definition)) {
      return "Type";
    } else if (isPrimitive(definition)) {
      return "Primitive";
    } else if (isComposite(definition)) {
      return "Composite";
    }
    return "";
  }

  protected String getOutputFileName(final Definition definition) {
    return fullyQualifiedNameToPath(definition.getName(), HTMLDocumentationHelper.ADL_DOC_EXT);
  }

  @SuppressWarnings("unchecked")
  @Override
  protected Class getTemplateLexer() {
    return DefaultTemplateLexer.class;
  }

  @Override
  protected void registerCustomRenderer(final StringTemplateGroup templateGroup) {
    templateGroup.registerRenderer(String.class, new HTMLRenderer());
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy