Java tutorial
/** * Copyright (C) 2009 STMicroelectronics * * This file is part of "Mind Compiler" is free software: you can redistribute * it and/or modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * * Contact: mind@ow2.org * * Authors: ali-erdem.ozcan@st.com * Contributors: */ package org.ow2.mind.doc.adl; import static org.objectweb.fractal.adl.types.TypeInterfaceUtil.isClient; import static org.objectweb.fractal.adl.types.TypeInterfaceUtil.isServer; import static org.ow2.mind.PathHelper.fullyQualifiedNameToPath; import static org.ow2.mind.adl.ast.ASTHelper.isComposite; import static org.ow2.mind.adl.ast.ASTHelper.isPrimitive; import static org.ow2.mind.adl.ast.ASTHelper.isType; import static org.ow2.mind.doc.HTMLDocumentationHelper.getAttributeAnchor; import static org.ow2.mind.doc.HTMLDocumentationHelper.getBindingAnchor; import static org.ow2.mind.doc.HTMLDocumentationHelper.getImplementationAnchor; import static org.ow2.mind.doc.HTMLDocumentationHelper.getInterfaceAnchor; import static org.ow2.mind.doc.HTMLDocumentationHelper.getPathToRoot; import static org.ow2.mind.doc.HTMLDocumentationHelper.getSubComponentAnchor; import java.io.File; import java.io.FileInputStream; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.PrintWriter; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import org.antlr.stringtemplate.StringTemplate; import org.antlr.stringtemplate.StringTemplateGroup; import org.antlr.stringtemplate.language.DefaultTemplateLexer; import org.apache.commons.io.IOUtils; 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.ow2.mind.SourceFileWriter; import org.ow2.mind.adl.AbstractSourceGenerator; import org.ow2.mind.adl.DefinitionSourceGenerator; import org.ow2.mind.adl.ast.ASTHelper; import org.ow2.mind.adl.ast.Attribute; import org.ow2.mind.adl.ast.AttributeContainer; import org.ow2.mind.adl.ast.Binding; import org.ow2.mind.adl.ast.BindingContainer; import org.ow2.mind.adl.ast.Component; import org.ow2.mind.adl.ast.ComponentContainer; import org.ow2.mind.adl.ast.Data; import org.ow2.mind.adl.ast.DefinitionReference; import org.ow2.mind.adl.ast.ImplementationContainer; import org.ow2.mind.adl.ast.Source; import org.ow2.mind.adl.generic.ast.FormalTypeParameter; import org.ow2.mind.adl.generic.ast.FormalTypeParameterContainer; import org.ow2.mind.adl.generic.ast.TypeArgument; import org.ow2.mind.adl.generic.ast.TypeArgumentContainer; import org.ow2.mind.doc.HTMLDocumentationHelper; import org.ow2.mind.doc.HTMLRenderer; import org.ow2.mind.doc.Launcher; import org.ow2.mind.doc.HTMLDocumentationHelper.SourceKind; import org.ow2.mind.doc.comments.CommentProcessor; import org.ow2.mind.io.IOErrors; public class HTMLDocumentGenerator extends AbstractSourceGenerator implements DefinitionSourceGenerator { public String pathToRoot; private File outputFile; public HTMLDocumentGenerator() { super("st.definitions.documentation.Component"); } public void visit(final Definition definition, final Map<Object, Object> context) throws ADLException { outputFile = outputFileLocatorItf.getCSourceOutputFile(getOutputFileName(definition), context); pathToRoot = getPathToRoot(definition.getName()); addDecorations(definition, (File) context.get("sourceDirectory")); final StringTemplate st = getInstanceOf("ComponentDocumentation"); st.setAttribute("definition", definition); final Map<String, Map<String, String>> 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); try { SourceFileWriter.writeToFile(outputFile, st.toString()); } catch (final IOException e) { throw new CompilerError(IOErrors.WRITE_ERROR, e, outputFile.getAbsolutePath()); } } private Map<String, String> getSectionAnchors(final Definition definition, final Map<String, Map<String, String>> anchorMap) { final Map<String, String> map = new HashMap<String, String>(); 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<String, Map<String, String>> getAnchorMap(final Definition definition) { final Map<String, Map<String, String>> superMap = new HashMap<String, Map<String, String>>(); Map<String, String> map = new HashMap<String, String>(); 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<String, String>(); 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<String, String>(); 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<String, String>(); 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<String, String>(); 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<String, Map<String, String>> getLinkMap(final Definition definition, final File sourceDirectory) throws ADLException { final Map<String, Map<String, String>> superMap = new HashMap<String, Map<String, String>>(); Map<String, String> map = new HashMap<String, String>(); 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<String, String>(); 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<String, String>(); superMap.put("impl", map); if (definition instanceof ImplementationContainer) { final ImplementationContainer implContainer = (ImplementationContainer) definition; for (final Source src : implContainer.getSources()) { final String sourceFileName = src.getPath().toString(); final String destFileName = "impl" + src.hashCode() + ".html"; String dest = null; dest = copySourceToHTML(sourceDirectory, sourceFileName, destFileName); if (dest != null) map.put(src.toString(), dest); } } return superMap; } private String copySourceToHTML(final File sourceDirectory, String sourceFileName, final String destFileName) { String dest = null; if (sourceFileName.startsWith("/")) { sourceFileName = sourceFileName.substring(1); } final File sourceFile = new File(sourceDirectory, sourceFileName); if (!sourceFile.canRead()) { Launcher.logger.warning("Cannot read implementation file '" + sourceFileName.toString() + "'."); } else { try { final File destinationFile = new File(outputFile.getParentFile(), destFileName); final FileWriter out = new FileWriter(destinationFile); final PrintWriter writer = new PrintWriter(out); final InputStream in = new FileInputStream(sourceFile); writer.print("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n" + "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n" + "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n" + "<head>\n" + "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />\n"); writer.printf("<title>%s</title>\n", sourceFileName); writer.println("</head>"); writer.println("<body>"); writer.println("<pre>"); IOUtils.copy(in, out); writer.println("</pre>"); writer.println("</body>"); writer.println("</html>"); writer.close(); in.close(); dest = destinationFile.getName(); } catch (final IOException e) { Launcher.logger.warning("Cannot copy implementation file '" + sourceFileName.toString() + "'. Reason: " + e.getLocalizedMessage()); } } return dest; } private void addDefinitionReferenceLink(final Definition definition, final Map<String, String> map, final DefinitionReference definitionReference) { map.put(definitionReference.getName(), HTMLDocumentationHelper.getRelativePathToADL(definition.getName(), definitionReference.getName(), SourceKind.COMPONENT)); } private void addTypeArgumentLinks(final Definition definition, final Map<String, String> 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 void addDecorations(final Definition definition, final File sourceDirectory) throws ADLException { setDefinitionKind(definition); HTMLDocumentationHelper.addAnnotationDecoration(definition); final List<Interface> clientInterfaces = new LinkedList<Interface>(); final List<Interface> serverInterfaces = new LinkedList<Interface>(); 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) { final String sourceFileName = data.getPath().toString(); final String destFileName = "data" + data.hashCode() + ".html"; String dest = null; dest = copySourceToHTML(sourceDirectory, sourceFileName, destFileName); if (dest != null) data.astSetDecoration("link", dest); } } 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()); } }