@Override protected Object[] doInBackground() throws Exception { IOFileFilter pdfFilter = FileFilterUtils.asFileFilter(this); IOFileFilter suffixFilter = FileFilterUtils.notFileFilter(new SuffixFileFilter(".fo")); IOFileFilter sheetFilter = FileFilterUtils.prefixFileFilter(Constants.CHARACTER_TEMPLATE_PREFIX); IOFileFilter fileFilter = FileFilterUtils.and(pdfFilter, suffixFilter, sheetFilter); IOFileFilter dirFilter = FileFilterUtils.makeSVNAware(TrueFileFilter.INSTANCE); File dir = new File(ConfigurationSettings.getOutputSheetsDir()); Collection<File> files = FileUtils.listFiles(dir, fileFilter, dirFilter); URI osPath = new File(ConfigurationSettings.getOutputSheetsDir()).toURI(); Object[] uriList = new Object[files.size()]; int i = 0; for (File file : files) { uriList[i] = osPath.relativize(file.toURI()); i++; } return uriList; }
/** * Commons-based FileSystem implementation * * @author Joe Walnes * @author Mauro Talevi */ public class CommonsFileSystem implements FileSystem { private static final IOFileFilter SVN_AWARE_FILTER = FileFilterUtils.makeSVNAware(null); public String readFile(File file) { try { return readFileToString(file); } catch (Exception e) { throw new FileSystemException("Cannot read content from file " + file, e); } } public void copyFile(File source, File destination) { try { copyFile(source, destination); } catch (Exception e) { throw new FileSystemException("Failed to copy file " + source + " to " + destination, e); } } public void copyDirectory(File sourceDirectory, File targetDirectory, boolean recurse) { if (!sourceDirectory.isDirectory()) { throw new FileSystemException("Source must be a directory " + sourceDirectory, null); } try { Collection<File> relativeFiles = filterRelativeFiles(sourceDirectory, getFileFilter(), recurse); for (File relativeFile : relativeFiles) { File sourceFile = new File(sourceDirectory, relativeFile.getPath()); File relativeDirectory = new File(targetDirectory, relativeFile.getParent()); copyFileToDirectory(sourceFile, relativeDirectory); } } catch (Exception e) { throw new FileSystemException( "Failed to copy directory " + sourceDirectory + " to " + targetDirectory, e); } } @SuppressWarnings("unchecked") private Collection<File> filterRelativeFiles( File sourceDirectory, IOFileFilter filter, boolean recurse) { Collection<File> files = listFiles( sourceDirectory, makeFileOnly(filter), (recurse ? makeDirectoryOnly(filter) : null)); Collection<File> relativeFiles = new ArrayList<File>(); String sourceDirectoryPath = sourceDirectory.getPath(); for (File file : files) { String filePath = file.getPath(); String relativePath = difference(sourceDirectoryPath, filePath); relativeFiles.add(new File(relativePath)); } return relativeFiles; } /** * Specifies the file filter used in the #copyDirectory() method. * * @return An IOFileFilter */ protected IOFileFilter getFileFilter() { return SVN_AWARE_FILTER; } @SuppressWarnings("serial") public static class FileSystemException extends RuntimeException { public FileSystemException(String message, Throwable throwable) { super(message, throwable); } } }
/** * Generate the "Source view" documentation from the sources, like Flex/Flash Builder does for the * release builds. Users can they right click the application and view the sources. * * <p>This goal produces a syntax highlighted version of the as, mxml and html documents in the * sources, and just copies other types of files. It also generates a navigation to browse the * sources. * * @goal source-view * @phase prepare-package */ public class SourceViewMojo extends AbstractIrvinMojo { /** * The Maven project. * * @parameter expression="${project}" * @required * @readonly */ protected MavenProject project; /** * The name of the directory containing the "View source" documentation. * * <p>It must be the same as the one declared in the Flex application: * * <pre> * <mx:Application [...] viewSourceURL="srcview"> * [...] * </mx:Application> * </pre> * * @parameter default-value="srcview" */ protected String sourceViewDirectoryName; /** * Encoding to use for the generated documentation. * * @parameter default-value="UTF-8" */ protected String outputEncoding; /** The instance of {@link VelocityEngine}. */ protected VelocityEngine velocityEngine; /** The instance of {@link VelocityContext}. */ protected VelocityContext velocityContext; /** The file filter to use when processing source files. */ protected IOFileFilter filter = FileFilterUtils.makeCVSAware(FileFilterUtils.makeSVNAware(null)); /** {@inheritDoc} */ @Override protected void setUp() throws MojoExecutionException, MojoFailureException { // Initialize a Velocity engine if (velocityEngine == null) { velocityEngine = new VelocityEngine(); try { Properties p = new Properties(); p.setProperty(VelocityEngine.RESOURCE_LOADER, "classpath"); p.setProperty( "classpath." + VelocityEngine.RESOURCE_LOADER + ".class", ClasspathResourceLoader.class.getName()); p.setProperty(VelocityEngine.RUNTIME_LOG_LOGSYSTEM_CLASS, NullLogSystem.class.getName()); p.setProperty(VelocityEngine.VM_CONTEXT_LOCALSCOPE, Boolean.toString(true)); velocityEngine.init(p); } catch (Exception e) { throw new MojoFailureException("Failed to initialize Velocity engine", e); } } // Initialize a Velocity context velocityContext = new VelocityContext(); } /** {@inheritDoc} */ @Override protected void run() throws MojoExecutionException, MojoFailureException { // Create the "Source view" directory File sourceViewDirectory = new File(project.getBuild().getDirectory() + File.separator + sourceViewDirectoryName); sourceViewDirectory.mkdirs(); // Start processing the main source directory processDirectory(new File(project.getBuild().getSourceDirectory()), sourceViewDirectory); // Initialize contents of the Velocity context velocityContext.put("sourceViewDirectory", sourceViewDirectory); velocityContext.put("project", project); velocityContext.put("contentFrameSource", getContentFrameSource()); // Generate the HTML pages from the templates processTemplate("index.html", sourceViewDirectory); processTemplate("navigation.html", sourceViewDirectory); processTemplate("style.css", sourceViewDirectory); } /** {@inheritDoc} */ @Override protected void tearDown() throws MojoExecutionException, MojoFailureException {} /** * Loop through source files in the directory and syntax highlight and/or copy them to the target * directory. * * @param directory The source directory to process. * @param targetDirectory The directory where to store the output. */ protected void processDirectory(File directory, File targetDirectory) { getLog().debug("Processing directory " + directory.getName()); // Loop through files in the directory for (File file : directory.listFiles((FileFilter) filter)) { // Skip hidden files if (!file.isHidden() && !file.getName().startsWith(".")) { if (file.isDirectory()) { File newTargetDirectory = new File(targetDirectory, file.getName()); newTargetDirectory.mkdir(); processDirectory(file, newTargetDirectory); } else { try { processFile(file, targetDirectory); } catch (IOException e) { getLog().warn("Error while processing " + file.getName(), e); } } } } } /** * Syntax highlight and/or copy the source file to the target directory. * * @param file The file to process. * @param targetDirectory The directory where to store the output. * @throws IOException If there was a file read/write exception. */ protected void processFile(File file, File targetDirectory) throws IOException { getLog().debug("Processing file " + file.getName()); // Prepare to copy the file String destinationFilePath = targetDirectory.getCanonicalPath() + File.separator + file.getName(); // Check if the file can be syntax highlighted String extension = file.getName().substring(file.getName().lastIndexOf('.') + 1); String highlightFilter = getHighlightFilter(extension); if (highlightFilter != null) { getLog().debug("Converting " + file.getName() + "to HTML."); destinationFilePath += ".html"; XhtmlRendererFactory.getRenderer(highlightFilter) .highlight( file.getName(), new FileInputStream(file), new FileOutputStream(destinationFilePath), Charset.forName(outputEncoding).name(), false); } else { getLog().debug("Copying " + file.getName()); FileUtils.copyFileToDirectory(file, targetDirectory); } } /** * Get the syntax highlighting filter to use for a file extension. * * @param fileExtension the file extension to test. * @return null if no filter available for this file type. * @see {@link XhtmlRendererFactory#getSupportedTypes()} */ protected String getHighlightFilter(String fileExtension) { // FIXME Using file extensions are less trustable than getting the real // filetype... if (fileExtension != null && !"".equals(fileExtension)) { if ("as".equals(fileExtension)) { return XhtmlRendererFactory.JAVA; } else if (fileExtension.startsWith("xml") || fileExtension.endsWith("xml")) { return XhtmlRendererFactory.XML; } else if (fileExtension.startsWith("htm") || fileExtension.startsWith("xhtm")) { return XhtmlRendererFactory.XHTML; } } return null; } /** * Merge the given template with the {@link SourceViewMojo#velocityContext} and produce the file * in the output documentation. * * @param templateName The name of the template to process. * @param targetDirectory The directory where to store the output file. * @throws MojoFailureException If the template could not be loaded, parsed, or the output file * could not be written. */ protected void processTemplate(String templateName, File targetDirectory) throws MojoFailureException { FileWriterWithEncoding pageWriter = null; try { pageWriter = new FileWriterWithEncoding( new File(targetDirectory.getCanonicalPath() + File.separator + templateName), Charset.forName(outputEncoding)); velocityEngine.mergeTemplate( "/templates/source-view/" + templateName + ".vm", Charset.forName("UTF-8").name(), velocityContext, pageWriter); } catch (ResourceNotFoundException e) { throw new MojoFailureException("The template '" + templateName + "' could not be found.", e); } catch (ParseErrorException e) { throw new MojoFailureException("Failed to parse the template '" + templateName + "' .", e); } catch (Exception e) { throw new MojoFailureException("Failed to load the template '" + templateName + "' .", e); } finally { try { pageWriter.close(); } catch (IOException e) { throw new MojoFailureException("Failed to write the template '" + templateName + "' .", e); } } } /** * Resolve the file to assign as the source of the content frame in the generated documentation. * * <p>Tries to resolve the main source and defaults to a blank page if not found. * * @return The path to the page to use in the generated documentation. */ @SuppressWarnings("unchecked") protected String getContentFrameSource() { File mainSourceFile = SourceFileResolver.resolveSourceFile( project.getCompileSourceRoots(), null, project.getGroupId(), project.getArtifactId()); return (mainSourceFile == null) ? "about:blank" : mainSourceFile.getName() + ".html"; } }