blob: 266558f627467b5ff027b599682749a218545a72 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.myfaces.buildtools.maven2.plugin.tagdoc;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import org.apache.maven.doxia.sink.Sink;
import org.apache.maven.doxia.siterenderer.Renderer;
import org.apache.maven.project.MavenProject;
import org.apache.maven.reporting.AbstractMavenReport;
import org.apache.maven.reporting.MavenReportException;
import org.apache.myfaces.buildtools.maven2.plugin.builder.Flattener;
import org.apache.myfaces.buildtools.maven2.plugin.builder.IOUtils;
import org.apache.myfaces.buildtools.maven2.plugin.builder.model.BehaviorMeta;
import org.apache.myfaces.buildtools.maven2.plugin.builder.model.ClassMeta;
import org.apache.myfaces.buildtools.maven2.plugin.builder.model.ComponentMeta;
import org.apache.myfaces.buildtools.maven2.plugin.builder.model.ConverterMeta;
import org.apache.myfaces.buildtools.maven2.plugin.builder.model.FaceletFunctionMeta;
import org.apache.myfaces.buildtools.maven2.plugin.builder.model.FaceletTagMeta;
import org.apache.myfaces.buildtools.maven2.plugin.builder.model.Model;
import org.apache.myfaces.buildtools.maven2.plugin.builder.model.TagMeta;
import org.apache.myfaces.buildtools.maven2.plugin.builder.model.ValidatorMeta;
import org.apache.myfaces.buildtools.maven2.plugin.builder.utils.MyfacesUtils;
import org.apache.velocity.runtime.resource.ResourceManagerImpl;
/**
* Report for generating JSF tagdoc index based on myfaces-metadata.xml parsing.
* The content is generated using velocity in xdoc files (see TagdocContentMojo).
*
* @author Leonardo Uribe
* @goal tagdoc-index
*/
public class TagdocIndexReport extends AbstractMavenReport
{
private Model _model;
/**
* Specifies the directory where the report will be generated
*
* @parameter default-value="${project.reporting.outputDirectory}"
* @required
*/
private File outputDirectory;
/**
* Directory where the original site is present.
* (TRIED using ${baseDir}/src/site; that inserted a 'null' into
* the string for some reason. TRIED using ${siteDirectory},
* which was undefined. TRIED ${project.directory}src/site; which also
* inserted a null. ${project.build.directory}/../src/site seems to work,
* though it assumes that ${project.build.directory} is
* ${project.directory}/target.
*
* @parameter default-value="${project.build.directory}/../src/site/"
* @required
*/
private File siteDirectory;
/**
* @parameter expression="${project}"
* @required
* @readonly
*/
private MavenProject project;
/**
* @component
*/
private Renderer siteRenderer;
/**
* @parameter
*/
private Map taglibs;
/**
* @parameter expression="${project.build.directory}/generated-resources/myfaces-builder-plugin"
*/
private File buildDirectory;
/**
* Injected name of file generated by earlier run of BuildMetaDataMojo goal.
*
* @parameter
*/
private String metadataFile = "META-INF/myfaces-metadata.xml";
/**
* @parameter
*/
private List modelIds;
/**
* component role="org.codehaus.plexus.velocity.VelocityComponent" roleHint="tagdoc"
*/
//private VelocityComponent velocityComponent;
static private final String _DOC_SUBDIRECTORY = "tagdoc";
protected void executeReport(Locale locale) throws MavenReportException
{
if (modelIds == null)
{
modelIds = new ArrayList();
modelIds.add(project.getArtifactId());
}
if (taglibs == null)
{
taglibs = new HashMap();
taglibs.put("t", "http://myfaces.apache.org/tomahawk");
}
try
{
_model = IOUtils.loadModel(new File(buildDirectory, metadataFile));
new Flattener(_model).flatten();
_generateTagDocs();
}
catch (Exception e)
{
throw new MavenReportException("Couldn't generate tagdoc", e);
}
}
public boolean canGenerate(ClassMeta component)
{
if (modelIds.contains(component.getModelId()))
{
return true;
}
else
{
return false;
}
}
public boolean canGenerate(FaceletFunctionMeta component)
{
if (modelIds.contains(component.getModelId()))
{
return true;
}
else
{
return false;
}
}
public class CustomResourceManagerImpl extends ResourceManagerImpl
{
public CustomResourceManagerImpl()
{
super();
}
}
private void _generateTagDocs() throws Exception
{
Model model = getModel();
if (model.getComponents().size() == 0)
{
getLog().info("Nothing to generate - no components found");
return;
}
Iterator components = model.components();
Iterator validators = model.validators();
Iterator converters = model.converters();
Iterator behaviors = model.behaviors();
Iterator tags = model.tags();
Iterator faceletTags = model.faceletTags();
Iterator faceletFunctions = model.faceletFunctions();
Map<String, List<FaceletFunctionMeta>> faceletFunctionByModelId =
new HashMap<String, List<FaceletFunctionMeta>>();
// =-=AEW Note that only updating out-of-date components, etc. is
// permanently tricky, even if we had proper detection in place,
// because the index always has to have all docs
/*
if (!components.hasNext() && !converters.hasNext() && !validators.hasNext())
{
getLog().info("Nothing to generate - all docs are up to date");
return;
}
*/
Set componentPages = new TreeSet();
Set converterPages = new TreeSet();
Set behaviorPages = new TreeSet();
Set validatorPages = new TreeSet();
Set tagsPages = new TreeSet();
Set faceletTagPages = new TreeSet();
Set faceletFunctionPages = new TreeSet();
int count = 0;
while (components.hasNext())
{
ComponentMeta component = (ComponentMeta) components.next();
if (canGenerate(component))
{
String pageName = _generateComponentDoc(component);
if (pageName != null)
{
componentPages.add(pageName);
count++;
}
}
}
while (converters.hasNext())
{
ConverterMeta converter = (ConverterMeta) converters.next();
if (canGenerate(converter))
{
String pageName = _generateConverterDoc(converter);
if (pageName != null)
{
converterPages.add(pageName);
count++;
}
}
}
while (validators.hasNext())
{
ValidatorMeta validator = (ValidatorMeta) validators.next();
if (canGenerate(validator))
{
String pageName = _generateValidatorDoc(validator);
if (pageName != null)
{
validatorPages.add(pageName);
count++;
}
}
}
while (behaviors.hasNext())
{
BehaviorMeta behavior = (BehaviorMeta) behaviors.next();
if (canGenerate(behavior))
{
String pageName = _generateBehaviorDoc(behavior);
if (pageName != null)
{
behaviorPages.add(pageName);
count++;
}
}
}
while (tags.hasNext())
{
TagMeta tag = (TagMeta) tags.next();
if (canGenerate(tag))
{
String pageName = _generateTagDoc(tag);
if (pageName != null)
{
tagsPages.add(pageName);
count++;
}
}
}
while (faceletTags.hasNext())
{
FaceletTagMeta faceletTag = (FaceletTagMeta) faceletTags.next();
if (canGenerate(faceletTag))
{
String pageName = _generateFaceletTagDoc(model, faceletTag);
if (pageName != null)
{
faceletTagPages.add(pageName);
count++;
}
}
}
for (int i = 0; i < modelIds.size(); i++)
{
String modelId = (String) modelIds.get(i);
faceletFunctionByModelId.put(modelId, new ArrayList<FaceletFunctionMeta>());
}
while (faceletFunctions.hasNext())
{
FaceletFunctionMeta faceletFunction = (FaceletFunctionMeta) faceletFunctions.next();
if (canGenerate(faceletFunction))
{
String pageName = _generateFaceletFunctionDoc(model, faceletFunction);
if (pageName != null)
{
faceletFunctionPages.add(pageName);
count++;
}
}
}
Set otherPages = _gatherOtherTags();
getLog().info("Generated " + count + " page(s)");
Sink sink = getSink();
sink.head();
sink.title();
sink.text("Tag library documentation");
sink.title_();
sink.head_();
sink.body();
sink.sectionTitle1();
sink.text("Tag library information");
sink.sectionTitle1_();
sink.section1();
for (Iterator i = taglibs.entrySet().iterator(); i.hasNext();)
{
Map.Entry entry = (Map.Entry) i.next();
sink.paragraph();
sink.bold();
sink.text("Short name:");
sink.bold_();
sink.nonBreakingSpace();
sink.text(entry.getKey().toString());
sink.lineBreak();
sink.bold();
sink.text("Namespace:");
sink.bold_();
sink.nonBreakingSpace();
sink.text(entry.getValue().toString());
sink.lineBreak();
sink.paragraph_();
}
sink.section1_();
_writeIndexSection(sink, componentPages, "Components");
_writeIndexSection(sink, converterPages, "Converters");
_writeIndexSection(sink, validatorPages, "Validators");
_writeIndexSection(sink, behaviorPages, "Behaviors");
_writeIndexSection(sink, tagsPages, "JSF Tags");
_writeIndexSection(sink, faceletTagPages, "JSF Facelet Tags");
_writeIndexSection(sink, faceletFunctionPages, "JSF Facelet EL Functions", "Function Name");
_writeIndexSection(sink, otherPages, "Miscellaneous");
sink.body_();
}
private Set _gatherOtherTags()
{
TreeSet set = new TreeSet();
String subDir = _platformAgnosticPath(_platformAgnosticPath("xdoc/"
+ _DOC_SUBDIRECTORY));
File siteSubDir = new File(siteDirectory, subDir);
if (siteSubDir.exists())
{
String[] files = siteSubDir.list();
for (int i = 0; i < files.length; i++)
{
String file = files[i];
if (file.endsWith(".xml"))
{
set.add(file.substring(0, file.length() - 4));
}
}
}
return set;
}
private void _writeIndexSection(Sink sink, Set pages, String title)
{
_writeIndexSection(sink, pages, title, "Tag Name");
}
private void _writeIndexSection(Sink sink, Set pages, String title, String typeName)
{
if (pages.isEmpty())
{
return;
}
sink.sectionTitle1();
sink.text(title);
sink.sectionTitle1_();
sink.section1();
sink.table();
sink.tableRow();
sink.tableHeaderCell();
sink.text(typeName);
sink.tableHeaderCell_();
sink.tableRow_();
Iterator iter = pages.iterator();
while (iter.hasNext())
{
sink.tableRow();
sink.tableCell();
String name = (String) iter.next();
String tagName = "<" + name.replace('_', ':') + ">";
sink.link(_DOC_SUBDIRECTORY + "/" + name + ".html");
sink.text(tagName);
sink.link_();
sink.tableCell_();
sink.tableRow_();
}
sink.table_();
sink.section1_();
}
public boolean usePageLinkBar()
{
return false;
}
private String _toPageName(String qName)
{
return MyfacesUtils.getTagPrefix(qName) + "_"
+ MyfacesUtils.getTagName(qName);
}
private String _generateComponentDoc(ComponentMeta component)
throws Exception
{
if (component.getName() == null)
{
return null;
}
String pageName = _toPageName(component.getName());
return pageName;
}
private String _generateConverterDoc(ConverterMeta converter)
throws IOException
{
if (converter.getName() == null)
{
return null;
}
String pageName = _toPageName(converter.getName());
return pageName;
}
private String _generateBehaviorDoc(BehaviorMeta behavior)
throws IOException
{
if (behavior.getName() == null)
{
return null;
}
String pageName = _toPageName(behavior.getName());
return pageName;
}
private String _generateValidatorDoc(ValidatorMeta validator)
throws IOException
{
if (validator.getName() == null)
{
return null;
}
String pageName = _toPageName(validator.getName());
return pageName;
}
private String _generateTagDoc(TagMeta tag)
throws IOException
{
if (tag.getName() == null)
{
return null;
}
String pageName = _toPageName(tag.getName());
return pageName;
}
private String _generateFaceletFunctionDoc(Model model, FaceletFunctionMeta faceletFunction)
throws IOException
{
if (faceletFunction.getName() == null)
{
return null;
}
String pageName = _toPageName(faceletFunction.getName());
return pageName;
}
private String _generateFaceletTagDoc(Model model, FaceletTagMeta tag)
throws IOException
{
String name = tag.getName();
if (name == null)
{
return null;
}
if (tag.getComponentClass() != null)
{
ComponentMeta comp = model.findComponentByClassName(tag.getComponentClass());
if (name.equals(comp.getName()))
{
//Exists in jsp and in facelets, but has specific facelets properties
return null;
}
}
if (tag.getConverterClass() != null)
{
ConverterMeta comp = model.findConverterByClassName(tag.getConverterClass());
if (name.equals(comp.getName()))
{
//Exists in jsp and in facelets, but has specific facelets properties
return null;
}
}
if (tag.getValidatorClass() != null)
{
ValidatorMeta comp = model.findValidatorByClassName(tag.getValidatorClass());
if (name.equals(comp.getName()))
{
//Exists in jsp and in facelets, but has specific facelets properties
return null;
}
}
if (tag.getBehaviorClass() != null)
{
BehaviorMeta comp = model.findBehaviorByClassName(tag.getBehaviorClass());
if (name.equals(comp.getName()))
{
//Exists in jsp and in facelets, but has specific facelets properties
return null;
}
}
if (tag.getTagClass() != null)
{
TagMeta comp = model.findTagByClassName(tag.getTagClass());
if (name.equals(comp.getName()))
{
//Exists in jsp and in facelets, but has specific facelets properties
return null;
}
}
String pageName = _toPageName(tag.getName());
return pageName;
}
static private final String _platformAgnosticPath(String path)
{
return path.replace('/', File.separatorChar);
}
protected MavenProject getProject()
{
return project;
}
protected String getOutputDirectory()
{
return outputDirectory.getAbsolutePath();
}
protected Renderer getSiteRenderer()
{
return siteRenderer;
}
public String getName(Locale locale)
{
return "JSF Tag Documentation";
}
public String getDescription(Locale locale)
{
return "Documentation for JSF Tags";
}
public String getOutputName()
{
return "tagdoc";
}
protected Model getModel()
{
return _model;
}
}