Author: ltheussl Date: Fri Jun 19 14:48:55 2009 New Revision: 786524 URL: http://svn.apache.org/viewvc?rev=786524&view=rev Log: Factor out some re-usable stuff.
Added: maven/plugins/trunk/maven-pdf-plugin/src/main/java/org/apache/maven/plugins/pdf/DateBean.java (with props) maven/plugins/trunk/maven-pdf-plugin/src/main/java/org/apache/maven/plugins/pdf/DocumentDescriptorReader.java (with props) maven/plugins/trunk/maven-pdf-plugin/src/main/java/org/apache/maven/plugins/pdf/DocumentModelBuilder.java (with props) Modified: maven/plugins/trunk/maven-pdf-plugin/src/main/java/org/apache/maven/plugins/pdf/PdfMojo.java maven/plugins/trunk/maven-pdf-plugin/src/test/java/org/apache/maven/plugins/pdf/PdfMojoTest.java Added: maven/plugins/trunk/maven-pdf-plugin/src/main/java/org/apache/maven/plugins/pdf/DateBean.java URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-pdf-plugin/src/main/java/org/apache/maven/plugins/pdf/DateBean.java?rev=786524&view=auto ============================================================================== --- maven/plugins/trunk/maven-pdf-plugin/src/main/java/org/apache/maven/plugins/pdf/DateBean.java (added) +++ maven/plugins/trunk/maven-pdf-plugin/src/main/java/org/apache/maven/plugins/pdf/DateBean.java Fri Jun 19 14:48:55 2009 @@ -0,0 +1,207 @@ +package org.apache.maven.plugins.pdf; + +/* + * 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. + */ + +import java.text.SimpleDateFormat; + +import java.util.Date; +import java.util.Locale; +import java.util.TimeZone; + + +/** + * Simple bean to allow date interpolation in the document descriptor, i.e. + * <pre> + * ${year} = 2009 + * ${date} = 2009-05-17 + * </pre> + * @author ltheussl + * @version $Id$ + */ +public class DateBean +{ + private static final TimeZone UTC_TIME_ZONE = TimeZone.getTimeZone( "UTC" ); + + private static final SimpleDateFormat YEAR = new SimpleDateFormat( "yyyy", Locale.US ); + private static final SimpleDateFormat MONTH = new SimpleDateFormat( "MM", Locale.US ); + private static final SimpleDateFormat DAY = new SimpleDateFormat( "dd", Locale.US ); + private static final SimpleDateFormat HOUR = new SimpleDateFormat( "HH", Locale.US ); + private static final SimpleDateFormat MINUTE = new SimpleDateFormat( "mm", Locale.US ); + private static final SimpleDateFormat SECOND = new SimpleDateFormat( "ss", Locale.US ); + private static final SimpleDateFormat MILLI_SECOND = new SimpleDateFormat( "SSS", Locale.US ); + private static final SimpleDateFormat DATE = new SimpleDateFormat( "yyyy-MM-dd", Locale.US ); + private static final SimpleDateFormat TIME = new SimpleDateFormat( "HH:mm:ss\'Z\'", Locale.US ); + private static final SimpleDateFormat DATE_TIME = new SimpleDateFormat( "yyyy-MM-dd\'T\'HH:mm:ss\'Z\'", Locale.US ); + + static + { + YEAR.setTimeZone( UTC_TIME_ZONE ); + MONTH.setTimeZone( UTC_TIME_ZONE ); + DAY.setTimeZone( UTC_TIME_ZONE ); + HOUR.setTimeZone( UTC_TIME_ZONE ); + MINUTE.setTimeZone( UTC_TIME_ZONE ); + SECOND.setTimeZone( UTC_TIME_ZONE ); + MILLI_SECOND.setTimeZone( UTC_TIME_ZONE ); + DATE.setTimeZone( UTC_TIME_ZONE ); + TIME.setTimeZone( UTC_TIME_ZONE ); + DATE_TIME.setTimeZone( UTC_TIME_ZONE ); + } + + private Date date; + + /** + * Construct a new DateBean for the current Date. + */ + public DateBean() + { + this( new Date() ); + } + + /** + * Construct a new DateBean with a given Date. + * + * @param date the date to set. + */ + public DateBean( final Date date ) + { + this.date = date; + } + + /** + * Set the Date of this bean. + * + * @param date the date to set. + */ + public void setDate( final Date date ) + { + this.date = date; + } + + + /** + * @return the current year. + */ + public String getYear() + { + synchronized ( this ) + { + return YEAR.format( date ); + } + } + + /** + * @return the current month. + */ + public String getMonth() + { + synchronized ( this ) + { + return MONTH.format( date ); + } + } + + /** + * @return the current day. + */ + public String getDay() + { + synchronized ( this ) + { + return DAY.format( date ); + } + } + + /** + * @return the current hour. + */ + public String getHour() + { + synchronized ( this ) + { + return HOUR.format( date ); + } + } + + /** + * @return the current minute. + */ + public String getMinute() + { + synchronized ( this ) + { + return MINUTE.format( date ); + } + } + + /** + * @return the current second. + */ + public String getSecond() + { + synchronized ( this ) + { + return SECOND.format( date ); + } + } + + /** + * @return the current millisecond. + */ + public String getMillisecond() + { + synchronized ( this ) + { + return MILLI_SECOND.format( date ); + } + } + + /** + * @return the current date using the ISO 8601 format, i.e. <code>yyyy-MM-dd</code>. + */ + public String getDate() + { + synchronized ( this ) + { + return DATE.format( date ); + } + } + + /** + * @return the current time using the ISO 8601 format and UTC time zone, i.e. <code>HH:mm:ss'Z'</code>. + */ + public String getTime() + { + synchronized ( this ) + { + return TIME.format( date ); + } + } + + /** + * @return the current datetime using the ISO 8601 format, i.e. <code>yyyy-MM-dd'T'HH:mm:ss'Z'</code>. + */ + public String getDateTime() + { + synchronized ( this ) + { + return DATE_TIME.format( date ); + } + } +} Propchange: maven/plugins/trunk/maven-pdf-plugin/src/main/java/org/apache/maven/plugins/pdf/DateBean.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: maven/plugins/trunk/maven-pdf-plugin/src/main/java/org/apache/maven/plugins/pdf/DateBean.java ------------------------------------------------------------------------------ svn:keywords = "Author Date Id Revision" Added: maven/plugins/trunk/maven-pdf-plugin/src/main/java/org/apache/maven/plugins/pdf/DocumentDescriptorReader.java URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-pdf-plugin/src/main/java/org/apache/maven/plugins/pdf/DocumentDescriptorReader.java?rev=786524&view=auto ============================================================================== --- maven/plugins/trunk/maven-pdf-plugin/src/main/java/org/apache/maven/plugins/pdf/DocumentDescriptorReader.java (added) +++ maven/plugins/trunk/maven-pdf-plugin/src/main/java/org/apache/maven/plugins/pdf/DocumentDescriptorReader.java Fri Jun 19 14:48:55 2009 @@ -0,0 +1,157 @@ +package org.apache.maven.plugins.pdf; + +/* + * 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. + */ + +import java.io.File; +import java.io.IOException; +import java.io.Reader; +import java.io.StringReader; + +import java.util.Properties; + +import org.apache.maven.doxia.document.DocumentModel; +import org.apache.maven.doxia.document.io.xpp3.DocumentXpp3Reader; + +import org.apache.maven.plugin.logging.Log; +import org.apache.maven.project.MavenProject; + +import org.codehaus.plexus.interpolation.EnvarBasedValueSource; +import org.codehaus.plexus.interpolation.InterpolationException; +import org.codehaus.plexus.interpolation.Interpolator; +import org.codehaus.plexus.interpolation.MapBasedValueSource; +import org.codehaus.plexus.interpolation.ObjectBasedValueSource; +import org.codehaus.plexus.interpolation.RegexBasedInterpolator; +import org.codehaus.plexus.util.IOUtil; +import org.codehaus.plexus.util.ReaderFactory; +import org.codehaus.plexus.util.introspection.ReflectionValueExtractor; +import org.codehaus.plexus.util.xml.pull.XmlPullParserException; + +/** + * Read and filter a DocumentModel from a document descriptor file. + * + * @author ltheussl + * @version $Id$ + */ +public class DocumentDescriptorReader +{ + private final MavenProject project; + private final Log log; + + /** + * Constructor. + */ + public DocumentDescriptorReader() + { + this( null, null ); + } + + /** + * Constructor. + * + * @param project may be null. + */ + public DocumentDescriptorReader( final MavenProject project ) + { + this( project, null ); + } + + /** + * Constructor. + * + * @param project may be null. + * @param log may be null. + */ + public DocumentDescriptorReader( final MavenProject project, final Log log ) + { + this.project = project; + this.log = log; + } + + /** + * Read and filter the <code>docDescriptor</code> file. + * + * @param docDescriptor not null. + * @return a DocumentModel instance. + * @throws XmlPullParserException if an error occurs during parsing. + * @throws IOException if an error occurs during reading. + */ + public DocumentModel readAndFilterDocumentDescriptor( final File docDescriptor ) + throws XmlPullParserException, IOException + { + Reader reader = null; + try + { + // System properties + final Properties filterProperties = System.getProperties(); + // Project properties + if ( project != null && project.getProperties() != null ) + { + filterProperties.putAll( project.getProperties() ); + } + + final Interpolator interpolator = new RegexBasedInterpolator(); + interpolator.addValueSource( new MapBasedValueSource( filterProperties ) ); + interpolator.addValueSource( new EnvarBasedValueSource() ); + interpolator.addValueSource( new ObjectBasedValueSource( project ) + { + /** {...@inheritdoc} */ + public Object getValue( final String expression ) + { + try + { + return ReflectionValueExtractor.evaluate( expression, project ); + } + catch ( Exception e ) + { + addFeedback( "Failed to extract \'" + expression + "\' from: " + project, e ); + } + + return null; + } + } ); + + final DateBean bean = new DateBean(); + interpolator.addValueSource( new ObjectBasedValueSource( bean ) ); + + reader = ReaderFactory.newXmlReader( docDescriptor ); + + final String interpolatedDoc = interpolator.interpolate( IOUtil.toString( reader ) ); + + if ( log != null && log.isDebugEnabled() ) + { + log.debug( "Interpolated document descriptor (" + + docDescriptor.getAbsolutePath() + ")\n" + interpolatedDoc ); + } + + // No Strict + return new DocumentXpp3Reader().read( new StringReader( interpolatedDoc ), false ); + } + catch ( InterpolationException e ) + { + final IOException io = new IOException( "Error interpolating document descriptor" ); + io.initCause( e ); + throw io; + } + finally + { + IOUtil.close( reader ); + } + } +} Propchange: maven/plugins/trunk/maven-pdf-plugin/src/main/java/org/apache/maven/plugins/pdf/DocumentDescriptorReader.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: maven/plugins/trunk/maven-pdf-plugin/src/main/java/org/apache/maven/plugins/pdf/DocumentDescriptorReader.java ------------------------------------------------------------------------------ svn:keywords = "Author Date Id Revision" Added: maven/plugins/trunk/maven-pdf-plugin/src/main/java/org/apache/maven/plugins/pdf/DocumentModelBuilder.java URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-pdf-plugin/src/main/java/org/apache/maven/plugins/pdf/DocumentModelBuilder.java?rev=786524&view=auto ============================================================================== --- maven/plugins/trunk/maven-pdf-plugin/src/main/java/org/apache/maven/plugins/pdf/DocumentModelBuilder.java (added) +++ maven/plugins/trunk/maven-pdf-plugin/src/main/java/org/apache/maven/plugins/pdf/DocumentModelBuilder.java Fri Jun 19 14:48:55 2009 @@ -0,0 +1,319 @@ +package org.apache.maven.plugins.pdf; + +/* + * 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. + */ + + +import java.util.ArrayList; +import java.util.Date; +import java.util.Iterator; +import java.util.List; + +import org.apache.maven.doxia.document.DocumentAuthor; +import org.apache.maven.doxia.document.DocumentCover; +import org.apache.maven.doxia.document.DocumentMeta; +import org.apache.maven.doxia.document.DocumentModel; +import org.apache.maven.doxia.document.DocumentTOC; +import org.apache.maven.doxia.document.DocumentTOCItem; +import org.apache.maven.doxia.site.decoration.DecorationModel; +import org.apache.maven.doxia.site.decoration.Menu; +import org.apache.maven.doxia.site.decoration.MenuItem; +import org.apache.maven.model.Developer; +import org.apache.maven.project.MavenProject; + +import org.codehaus.plexus.util.StringUtils; + +/** + * Construct a DocumentModel from a MavenProject and related information. + * + * @author ltheussl + * @version $Id$ + */ +public class DocumentModelBuilder +{ + private final MavenProject project; + private final DecorationModel decorationModel; + + /** + * Constructor. Initialize a MavenProject to extract information from. + * + * @param project a MavenProject. May be null. + */ + public DocumentModelBuilder( MavenProject project ) + { + this( project, null ); + } + + /** + * Constructor. Initialize a MavenProject and a DecorationModel to extract information from. + * + * @param project a MavenProject. May be null. + * @param decorationModel a DecorationModel. May be null. + */ + public DocumentModelBuilder( MavenProject project, DecorationModel decorationModel ) + { + this.project = project; + this.decorationModel = decorationModel; + } + + /** + * Get a DocumentModel. + * + * @return a DocumentModel. Always non-null. + */ + public DocumentModel getDocumentModel() + { + return getDocumentModel( project, decorationModel, null ); + } + + /** + * Get a DocumentModel. + * + * @param date overrides the default date in meta- and cover information. + * @return a DocumentModel. Always non-null. + */ + public DocumentModel getDocumentModel( Date date ) + { + return getDocumentModel( project, decorationModel, date ); + } + + // ---------------------------------------------------------------------- + // Private methods + // ---------------------------------------------------------------------- + + /** + * Extract a DocumentModel from a MavenProject. + * + * @param project a MavenProject. May be null. + * @param decorationModel a DecorationModel. May be null. + * @param date the date of the TOC. May be null in which case the build date will be used. + * + * @return a DocumentModel. Always non-null. + */ + private static DocumentModel getDocumentModel( MavenProject project, + DecorationModel decorationModel, Date date ) + { + final Date now = ( date == null ? new Date() : date ); + + final DocumentModel docModel = new DocumentModel(); + + docModel.setModelEncoding( getProjectModelEncoding( project ) ); + docModel.setOutputName( project == null ? null : project.getArtifactId() ); + docModel.setMeta( getDocumentMeta( project, now ) ); + docModel.setCover( getDocumentCover( project, now ) ); + docModel.setToc( getDocumentTOC( decorationModel ) ); + + return docModel; + } + + /** + * Extract a DocumentTOC from a DecorationModel. + * + * @param decorationModel a DecorationModel. May be null. + * @return a DocumentTOC, always non-null. + */ + private static DocumentTOC getDocumentTOC( DecorationModel decorationModel ) + { + final DocumentTOC toc = new DocumentTOC(); + + if ( decorationModel != null && decorationModel.getMenus() != null ) + { + for ( final Iterator it = decorationModel.getMenus().iterator(); it.hasNext(); ) + { + final Menu menu = (Menu) it.next(); + + for ( final Iterator it2 = menu.getItems().iterator(); it2.hasNext(); ) + { + final MenuItem item = (MenuItem) it2.next(); + + final DocumentTOCItem documentTOCItem = new DocumentTOCItem(); + documentTOCItem.setName( item.getName() ); + documentTOCItem.setRef( item.getHref() ); + toc.addItem( documentTOCItem ); + } + } + } + + return toc; + } + + /** + * Extract meta information from a MavenProject. + * + * @param project a MavenProject. May be null. + * @param date the date to use in meta. May be null. + * + * @return a DocumentMeta object. Always non-null. + */ + private static DocumentMeta getDocumentMeta( MavenProject project, Date date ) + { + final DocumentMeta meta = new DocumentMeta(); + + meta.setAuthors( getAuthors( project ) ); + meta.setCreationDate( date ); + meta.setCreator( System.getProperty( "user.name" ) ); + meta.setDate( date ); + meta.setDescription( project == null ? null : project.getDescription() ); + //meta.setGenerator( generator ); + meta.setInitialCreator( System.getProperty( "user.name" ) ); + //meta.setLanguage( locale == null ? null : locale.getLanguage() ); + //meta.setPageSize( pageSize ); + meta.setSubject( getProjectName( project ) ); + meta.setTitle( getProjectName( project ) ); + + return meta; + } + + /** + * Extract information for a DocumentCover from a MavenProject. + * + * @param project a MavenProject. May be null. + * @param date the cover date. May be null. + * + * @return a DocumentCover object. Always non-null. + */ + private static DocumentCover getDocumentCover( MavenProject project, Date date ) + { + final DocumentCover cover = new DocumentCover(); + + cover.setAuthors( getAuthors( project ) ); + //cover.setCompanyLogo( companyLogo ); + cover.setCompanyName( getProjectOrganizationName( project ) ); + cover.setCoverDate( date ); + cover.setCoverSubTitle( project == null ? null : "v. " + project.getVersion() ); + cover.setCoverTitle( getProjectName( project ) ); + //cover.setCoverType( type ); + cover.setCoverVersion( project == null ? null : project.getVersion() ); + //cover.setProjectLogo( projectLogo ); + cover.setProjectName( getProjectName( project ) ); + + return cover; + } + + /** + * Wrap the list of project {...@link Developer} to a list of {...@link DocumentAuthor}. + * + * @param project the MavenProject to extract the authors from. + * @return a list of DocumentAuthors from the project developers. + * Returns null if project is null or contains no developers. + */ + private static List getAuthors( MavenProject project ) + { + if ( project == null || project.getDevelopers() == null ) + { + return null; + } + + final List ret = new ArrayList(); + + for ( final Iterator it = project.getDevelopers().iterator(); it.hasNext(); ) + { + final Developer developer = (Developer) it.next(); + + final DocumentAuthor author = new DocumentAuthor(); + author.setName( developer.getName() ); + author.setEmail( developer.getEmail() ); + author.setCompanyName( developer.getOrganization() ); + StringBuffer roles = null; + + for ( final Iterator it2 = developer.getRoles().iterator(); it2.hasNext(); ) + { + final String role = (String) it2.next(); + + if ( roles == null ) + { + roles = new StringBuffer(); + } + + roles.append( role ); + + if ( it2.hasNext() ) + { + roles.append( ',' ); + } + } + if ( roles != null ) + { + author.setPosition( roles.toString() ); + } + + ret.add( author ); + } + + return ret; + } + + /** + * @param project the MavenProject to extract the project organization name from. + * @return the project organization name if not empty, or the current System user name otherwise. + */ + private static String getProjectOrganizationName( MavenProject project ) + { + if ( project != null && project.getOrganization() != null + && StringUtils.isNotEmpty( project.getOrganization().getName() ) ) + { + return project.getOrganization().getName(); + } + + return System.getProperty( "user.name" ); + } + + /** + * Extract the name of the project. + * + * @param project the MavenProject to extract the project name from. + * @return the project name, or the project groupId and artifactId if + * the project name is empty, or null if project is null. + */ + private static String getProjectName( MavenProject project ) + { + if ( project == null ) + { + return null; + } + + if ( StringUtils.isEmpty( project.getName() ) ) + { + return project.getGroupId() + ":" + project.getArtifactId(); + } + + return project.getName(); + } + + /** + * Extract the encoding. + * + * @param project the MavenProject to extract the encoding name from. + * @return the project encoding if defined, or UTF-8 otherwise, or null if project is null. + */ + private static String getProjectModelEncoding( MavenProject project ) + { + if ( project == null ) + { + return null; + } + + if ( StringUtils.isEmpty( project.getModel().getModelEncoding() ) ) + { + return "UTF-8"; + } + + return project.getModel().getModelEncoding(); + } +} Propchange: maven/plugins/trunk/maven-pdf-plugin/src/main/java/org/apache/maven/plugins/pdf/DocumentModelBuilder.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: maven/plugins/trunk/maven-pdf-plugin/src/main/java/org/apache/maven/plugins/pdf/DocumentModelBuilder.java ------------------------------------------------------------------------------ svn:keywords = "Author Date Id Revision" Modified: maven/plugins/trunk/maven-pdf-plugin/src/main/java/org/apache/maven/plugins/pdf/PdfMojo.java URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-pdf-plugin/src/main/java/org/apache/maven/plugins/pdf/PdfMojo.java?rev=786524&r1=786523&r2=786524&view=diff ============================================================================== --- maven/plugins/trunk/maven-pdf-plugin/src/main/java/org/apache/maven/plugins/pdf/PdfMojo.java (original) +++ maven/plugins/trunk/maven-pdf-plugin/src/main/java/org/apache/maven/plugins/pdf/PdfMojo.java Fri Jun 19 14:48:55 2009 @@ -21,62 +21,39 @@ import java.io.File; import java.io.IOException; -import java.io.InputStream; -import java.io.Reader; import java.io.StringReader; import java.io.Writer; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Locale; -import java.util.Map; -import java.util.Properties; -import java.util.TimeZone; import org.apache.maven.artifact.repository.ArtifactRepository; import org.apache.maven.doxia.docrenderer.DocumentRenderer; import org.apache.maven.doxia.docrenderer.DocumentRendererException; import org.apache.maven.doxia.docrenderer.pdf.PdfRenderer; -import org.apache.maven.doxia.document.DocumentAuthor; -import org.apache.maven.doxia.document.DocumentCover; -import org.apache.maven.doxia.document.DocumentMeta; import org.apache.maven.doxia.document.DocumentModel; -import org.apache.maven.doxia.document.DocumentTOC; -import org.apache.maven.doxia.document.DocumentTOCItem; -import org.apache.maven.doxia.document.io.xpp3.DocumentXpp3Reader; import org.apache.maven.doxia.document.io.xpp3.DocumentXpp3Writer; import org.apache.maven.doxia.site.decoration.DecorationModel; -import org.apache.maven.doxia.site.decoration.Menu; -import org.apache.maven.doxia.site.decoration.MenuItem; import org.apache.maven.doxia.site.decoration.io.xpp3.DecorationXpp3Reader; import org.apache.maven.doxia.siterenderer.Renderer; import org.apache.maven.doxia.siterenderer.SiteRenderingContext; import org.apache.maven.doxia.tools.SiteTool; import org.apache.maven.doxia.tools.SiteToolException; -import org.apache.maven.model.Developer; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; -import org.apache.maven.plugin.logging.Log; import org.apache.maven.project.MavenProject; +//TODO: replace with something equivalent in plexus.util import org.apache.maven.wagon.PathUtils; + import org.codehaus.plexus.i18n.I18N; -import org.codehaus.plexus.interpolation.EnvarBasedValueSource; -import org.codehaus.plexus.interpolation.InterpolationException; -import org.codehaus.plexus.interpolation.Interpolator; -import org.codehaus.plexus.interpolation.MapBasedValueSource; -import org.codehaus.plexus.interpolation.ObjectBasedValueSource; -import org.codehaus.plexus.interpolation.RegexBasedInterpolator; import org.codehaus.plexus.util.FileUtils; import org.codehaus.plexus.util.IOUtil; import org.codehaus.plexus.util.ReaderFactory; import org.codehaus.plexus.util.StringUtils; import org.codehaus.plexus.util.WriterFactory; -import org.codehaus.plexus.util.introspection.ReflectionValueExtractor; import org.codehaus.plexus.util.xml.XmlStreamReader; import org.codehaus.plexus.util.xml.pull.XmlPullParserException; @@ -220,11 +197,21 @@ */ private DecorationModel defaultDecorationModel; + /** + * @parameter expression="${plugin.version}" + */ + private String pluginVersion; + // ---------------------------------------------------------------------- // Public methods // ---------------------------------------------------------------------- - /** {...@inheritdoc} */ + /** + * {...@inheritdoc} + * + * @throws MojoExecutionException if an exception ocurred during mojo execution. + * @throws MojoFailureException if the mojo could not be executed. + */ public void execute() throws MojoExecutionException, MojoFailureException { @@ -243,17 +230,17 @@ try { - List localesList = siteTool.getAvailableLocales( locales ); + final List localesList = siteTool.getAvailableLocales( locales ); // Default is first in the list - Locale defaultLocale = (Locale) localesList.get( 0 ); + this.defaultLocale = (Locale) localesList.get( 0 ); Locale.setDefault( defaultLocale ); - for ( Iterator iterator = localesList.iterator(); iterator.hasNext(); ) + for ( final Iterator iterator = localesList.iterator(); iterator.hasNext(); ) { - Locale locale = (Locale) iterator.next(); + final Locale locale = (Locale) iterator.next(); - File workingDir = getWorkingDirectory( locale, defaultLocale ); + final File workingDir = getWorkingDirectory( locale, defaultLocale ); File siteDirectoryFile = siteDirectory; if ( !locale.getLanguage().equals( defaultLocale.getLanguage() ) ) @@ -264,32 +251,36 @@ // Copy extra-resources copyResources( locale ); - if ( aggregate ) + try { - docRenderer.render( siteDirectoryFile, workingDir, getDocumentModel( locale ) ); + if ( aggregate ) + { + docRenderer.render( siteDirectoryFile, workingDir, getDocumentModel( locale ) ); + } + else + { + docRenderer.render( siteDirectoryFile, workingDir, null ); + } } - else + catch ( DocumentRendererException e ) { - docRenderer.render( siteDirectoryFile, workingDir, null ); + throw new MojoExecutionException( "Error during document generation", e ); } } if ( !outputDirectory.getCanonicalPath().equals( workingDirectory.getCanonicalPath() ) ) { - List pdfs = FileUtils.getFiles( workingDirectory, "**/*.pdf", null ); - for ( Iterator it = pdfs.iterator(); it.hasNext(); ) + final List pdfs = FileUtils.getFiles( workingDirectory, "**/*.pdf", null ); + + for ( final Iterator it = pdfs.iterator(); it.hasNext(); ) { - File pdf = (File) it.next(); + final File pdf = (File) it.next(); FileUtils.copyFile( pdf, new File( outputDirectory, pdf.getName() ) ); pdf.delete(); } } } - catch ( DocumentRendererException e ) - { - throw new MojoExecutionException( "Error during document generation", e ); - } catch ( IOException e ) { throw new MojoExecutionException( "Error during document generation", e ); @@ -312,23 +303,49 @@ * @see #readAndFilterDocumentDescriptor(MavenProject, File, Log) */ private DocumentModel getDocumentModel( Locale locale ) - throws DocumentRendererException, IOException, MojoExecutionException + throws MojoExecutionException { if ( docDescriptor.exists() ) { - DocumentModel doc = readAndFilterDocumentDescriptor( project, docDescriptor, getLog() ); + DocumentModel doc = null; + + try + { + doc = new DocumentDescriptorReader( project, getLog() ) + .readAndFilterDocumentDescriptor( docDescriptor ); + } + catch ( XmlPullParserException ex ) + { + throw new MojoExecutionException( "Error reading DocumentDescriptor!", ex ); + } + catch ( IOException io ) + { + throw new MojoExecutionException( "Error opening DocumentDescriptor!", io ); + } + if ( StringUtils.isEmpty( doc.getMeta().getLanguage() ) ) { doc.getMeta().setLanguage( locale.getLanguage() ); } + if ( StringUtils.isEmpty( doc.getMeta().getGenerator() ) ) { doc.getMeta().setGenerator( getDefaultGenerator() ); } + return doc; } - return generateDefaultDocDescriptor( locale ); + DocumentModel model = new DocumentModelBuilder( project, getDefaultDecorationModel() ).getDocumentModel(); + + model.getMeta().setGenerator( getDefaultGenerator() ); + model.getMeta().setLanguage( locale.getLanguage() ); + model.getCover().setCoverType( i18n.getString( "pdf-plugin", defaultLocale, "toc.type" ) ); + model.getToc().setName( i18n.getString( "pdf-plugin", defaultLocale, "toc.title" ) ); + + debugLogGeneratedModel( project, model ); + + return model; } /** @@ -349,199 +366,13 @@ } /** - * @param locale not null - * @return Generate a default document descriptor from the Maven project - * @throws IOException if any - * @throws MojoExecutionException if any - */ - private DocumentModel generateDefaultDocDescriptor( Locale locale ) - throws IOException, MojoExecutionException - { - DocumentMeta meta = new DocumentMeta(); - meta.setAuthors( getAuthors() ); - meta.setCreationDate( new Date() ); - meta.setCreator( System.getProperty( "user.name" ) ); - meta.setDate( new Date() ); - meta.setDescription( project.getDescription() ); - meta.setGenerator( getDefaultGenerator() ); - meta.setInitialCreator( System.getProperty( "user.name" ) ); - meta.setLanguage( locale.getLanguage() ); - //meta.setPageSize( pageSize ); - meta.setSubject( getProjectName() ); - meta.setTitle( getProjectName() ); - - DocumentCover cover = new DocumentCover(); - cover.setAuthors( getAuthors() ); - //cover.setCompanyLogo( companyLogo ); - cover.setCompanyName( getProjectOrganizationName() ); - cover.setCoverDate( new Date() ); - cover.setCoverSubTitle( "v. " + project.getVersion() ); - cover.setCoverTitle( getProjectName() ); - cover.setCoverType( i18n.getString( "pdf-plugin", getDefaultLocale(), "toc.type" ) ); - cover.setCoverVersion( project.getVersion() ); - //cover.setProjectLogo( projectLogo ); - cover.setProjectName( getProjectName() ); - - DocumentModel docModel = new DocumentModel(); - docModel.setModelEncoding( getProjectModelEncoding() ); - docModel.setOutputName( project.getArtifactId() ); - docModel.setMeta( meta ); - docModel.setCover( cover ); - - // Populate docModel from defaultDecorationModel - DecorationModel decorationModel = getDefaultDecorationModel(); - if ( decorationModel != null ) - { - DocumentTOC toc = new DocumentTOC(); - - toc.setName( i18n.getString( "pdf-plugin", getDefaultLocale(), "toc.title" ) ); - - for ( Iterator it = decorationModel.getMenus().iterator(); it.hasNext(); ) - { - Menu menu = (Menu) it.next(); - - for ( Iterator it2 = menu.getItems().iterator(); it2.hasNext(); ) - { - MenuItem item = (MenuItem) it2.next(); - - DocumentTOCItem documentTOCItem = new DocumentTOCItem(); - documentTOCItem.setName( item.getName() ); - documentTOCItem.setRef( item.getHref() ); - toc.addItem( documentTOCItem ); - } - } - - docModel.setToc( toc ); - } - - if ( getLog().isDebugEnabled() ) - { - File outputDir = new File( project.getBuild().getDirectory(), "pdf" ); - - if ( outputDir.isFile() ) - { - throw new IOException( outputDir + " is not a directory!" ); - } - - if ( !outputDir.exists() ) - { - outputDir.mkdirs(); - } - - File doc = FileUtils.createTempFile( "pdf", ".xml", outputDir ); - - getLog().debug( "Generated a default document model: " + doc.getAbsolutePath() ); - - DocumentXpp3Writer xpp3 = new DocumentXpp3Writer(); - Writer w = null; - try - { - w = WriterFactory.newXmlWriter( doc ); - xpp3.write( w, docModel ); - } - finally - { - IOUtil.close( w ); - } - } - - return docModel; - } - - /** - * @return the project organization name if not empty, or the current System user name otherwise. - */ - private String getProjectOrganizationName() - { - if ( project.getOrganization() != null && StringUtils.isNotEmpty( project.getOrganization().getName() ) ) - { - return project.getOrganization().getName(); - } - - return System.getProperty( "user.name" ); - } - - /** - * @return the project name if not empty, or the project groupId and artifactId. - */ - private String getProjectName() - { - if ( StringUtils.isEmpty( project.getName() ) ) - { - return project.getGroupId() + ":" + project.getArtifactId(); - } - - return project.getName(); - } - - /** - * @return the project encoding if defined, or UTF-8 otherwise. - */ - private String getProjectModelEncoding() - { - if ( StringUtils.isEmpty( project.getModel().getModelEncoding() ) ) - { - return "UTF-8"; - } - - return project.getModel().getModelEncoding(); - } - - /** - * Wrap the list of project {...@link Developer} to a list of {...@link DocumentAuthor}. - * - * @return a list of authors from the project developers. - */ - private List getAuthors() - { - if ( project.getDevelopers() == null ) - { - return null; - } - - List ret = new ArrayList(); - for ( Iterator it = project.getDevelopers().iterator(); it.hasNext(); ) - { - Developer developer = (Developer) it.next(); - - DocumentAuthor author = new DocumentAuthor(); - author.setName( developer.getName() ); - author.setEmail( developer.getEmail() ); - author.setCompanyName( developer.getOrganization() ); - StringBuffer roles = null; - for ( Iterator it2 = developer.getRoles().iterator(); it2.hasNext(); ) - { - String role = (String) it2.next(); - - if ( roles == null ) - { - roles = new StringBuffer(); - } - roles.append( role ); - if ( it2.hasNext() ) - { - roles.append( "," ); - } - } - if ( roles != null ) - { - author.setPosition( roles.toString() ); - } - - ret.add( author ); - } - - return ret; - } - - /** * @return the default locale from <code>siteTool</code>. */ private Locale getDefaultLocale() { if ( this.defaultLocale == null ) { - List localesList = siteTool.getAvailableLocales( locales ); + final List localesList = siteTool.getAvailableLocales( locales ); this.defaultLocale = (Locale) localesList.get( 0 ); } @@ -557,17 +388,15 @@ { if ( this.defaultDecorationModel == null ) { - Locale locale = getDefaultLocale(); + final Locale locale = getDefaultLocale(); - File descriptorFile = + final File descriptorFile = siteTool.getSiteDescriptorFromBasedir( PathUtils.toRelative( project.getBasedir(), siteDirectory.getAbsolutePath() ), project.getBasedir(), locale ); DecorationModel decoration = null; if ( descriptorFile.exists() ) { - Map props = new HashMap(); - XmlStreamReader reader = null; try { @@ -575,7 +404,7 @@ String siteDescriptorContent = IOUtil.toString( reader ); siteDescriptorContent = - siteTool.getInterpolatedSiteDescriptorContent( props, project, siteDescriptorContent, + siteTool.getInterpolatedSiteDescriptorContent( new HashMap(), project, siteDescriptorContent, reader.getEncoding(), reader.getEncoding() ); decoration = new DecorationXpp3Reader().read( new StringReader( siteDescriptorContent ) ); @@ -614,7 +443,7 @@ private void copyResources( Locale locale ) throws MojoExecutionException { - DecorationModel decorationModel = getDefaultDecorationModel(); + final DecorationModel decorationModel = getDefaultDecorationModel(); if ( decorationModel == null ) { @@ -622,6 +451,7 @@ } File skinFile; + try { skinFile = @@ -645,14 +475,14 @@ try { - SiteRenderingContext context = + final SiteRenderingContext context = siteRenderer.createContextForSkin( skinFile, new HashMap(), decorationModel, project.getName(), locale ); context.addSiteDirectory( new File( siteDirectory, locale.getLanguage() ) ); - for ( Iterator i = context.getSiteDirectories().iterator(); i.hasNext(); ) + for ( final Iterator i = context.getSiteDirectories().iterator(); i.hasNext(); ) { - File siteDirectoryFile = (File) i.next(); + final File siteDirectoryFile = (File) i.next(); siteRenderer.copyResources( context, new File( siteDirectoryFile, "resources" ), workingDirectory ); } @@ -664,201 +494,47 @@ } /** - * Read and filter the <code>docDescriptor</code> file. + * Construct a default producer. * - * @param project not null - * @param docDescriptor not null - * @param log not null - * @return a DocumentModel instance - * @throws DocumentRendererException if any - * @throws IOException if any + * @param version the current plugin version. May be null. + * @param implementation the pdf implementation. May be null. + * @return A String in the form <code>Maven PDF Plugin v. 1.1.1, 'fo' implementation</code>. */ - private DocumentModel readAndFilterDocumentDescriptor( final MavenProject project, File docDescriptor, Log log ) - throws DocumentRendererException, IOException + private String getDefaultGenerator() { - Reader reader = null; - try - { - // System properties - Properties filterProperties = System.getProperties(); - // Project properties - if ( project != null && project.getProperties() != null ) - { - filterProperties.putAll( project.getProperties() ); - } - - Interpolator interpolator = new RegexBasedInterpolator(); - interpolator.addValueSource( new MapBasedValueSource( filterProperties ) ); - interpolator.addValueSource( new EnvarBasedValueSource() ); - interpolator.addValueSource( new ObjectBasedValueSource( project ) - { - /** {...@inheritdoc} */ - public Object getValue( String expression ) - { - try - { - return ReflectionValueExtractor.evaluate( expression, project ); - } - catch ( Exception e ) - { - addFeedback( "Failed to extract \'" + expression + "\' from: " + project, e ); - } - - return null; - } - } ); - final DateBean bean = new DateBean(); - interpolator.addValueSource( new ObjectBasedValueSource( bean ) ); - - reader = ReaderFactory.newXmlReader( docDescriptor ); - - String interpolatedDoc = interpolator.interpolate( IOUtil.toString( reader ) ); - - if ( getLog().isDebugEnabled() ) - { - getLog().debug( - "Interpolated document descriptor (" + docDescriptor.getAbsolutePath() + ")\n" - + interpolatedDoc ); - } - - // No Strict - return new DocumentXpp3Reader().read( new StringReader( interpolatedDoc ), false ); - } - catch ( XmlPullParserException e ) - { - throw new DocumentRendererException( "Error parsing document descriptor", e ); - } - catch ( InterpolationException e ) - { - throw new DocumentRendererException( "Error interpolating document descriptor", e ); - } - finally - { - IOUtil.close( reader ); - } + return "Maven PDF Plugin v. " + pluginVersion + ", '" + implementation + "' implementation."; } - /** - * @return the PDF producer ie <code>Apache Doxia 1.1.1, 'fo' implementation</code> - */ - private String getDefaultGenerator() + private void debugLogGeneratedModel( MavenProject project, final DocumentModel docModel ) { - String doxiaVersion = "unknown"; - InputStream resourceAsStream; - try + if ( getLog().isDebugEnabled() && project != null ) { - Properties properties = new Properties(); - resourceAsStream = getClass().getClassLoader() - .getResourceAsStream( "META-INF/maven/org.apache.maven.doxia/doxia-core/pom.properties" ); + final File outputDir = new File( project.getBuild().getDirectory(), "pdf" ); - if ( resourceAsStream != null ) + if ( !outputDir.exists() ) { - properties.load( resourceAsStream ); - - doxiaVersion = properties.getProperty( "version", doxiaVersion ); + outputDir.mkdirs(); } - } - catch ( IOException e ) - { - getLog().error( "Unable to determine version from JAR file: " + e.getMessage() ); - } - - return "Apache Doxia " + doxiaVersion + ", '" + implementation + "' implementation."; - } - - /** - * Simple bean to allow date interpolation in the document descriptor, i.e. - * <pre> - * ${year} = 2009 - * ${date} = 2009-05-17 - * </pre> - */ - public static class DateBean - { - private static final TimeZone UTC_TIME_ZONE = TimeZone.getTimeZone( "UTC" ); - /** - * @return the current year. - */ - public String getYear() - { - return new SimpleDateFormat( "yyyy", Locale.US ).format( new Date() ); - } + final File doc = FileUtils.createTempFile( "pdf", ".xml", outputDir ); + final DocumentXpp3Writer xpp3 = new DocumentXpp3Writer(); - /** - * @return the current month. - */ - public String getMonth() - { - return new SimpleDateFormat( "MM", Locale.US ).format( new Date() ); - } - - /** - * @return the current day. - */ - public String getDay() - { - return new SimpleDateFormat( "dd", Locale.US ).format( new Date() ); - } - - /** - * @return the current hour. - */ - public String getHour() - { - return new SimpleDateFormat( "HH", Locale.US ).format( new Date() ); - } - - /** - * @return the current minute. - */ - public String getMinute() - { - return new SimpleDateFormat( "mm", Locale.US ).format( new Date() ); - } - - /** - * @return the current second. - */ - public String getSecond() - { - return new SimpleDateFormat( "ss", Locale.US ).format( new Date() ); - } - - /** - * @return the current millisecond. - */ - public String getMillisecond() - { - return new SimpleDateFormat( "SSS", Locale.US ).format( new Date() ); - } - - /** - * @return the current date using the ISO 8601 format, i.e. <code>yyyy-MM-dd</code>. - */ - public String getDate() - { - return new SimpleDateFormat( "yyyy-MM-dd", Locale.US ).format( new Date() ); - } - - /** - * @return the current time using the ISO 8601 format and UTC time zone, i.e. <code>HH:mm:ss'Z'</code>. - */ - public String getTime() - { - SimpleDateFormat sdf = new SimpleDateFormat( "HH:mm:ss'Z'", Locale.US ); - sdf.setTimeZone( UTC_TIME_ZONE ); - return sdf.format( new Date() ); - } + Writer w = null; - /** - * @return the current datetime using the ISO 8601 format, i.e. <code>yyyy-MM-dd'T'HH:mm:ss'Z'</code>. - */ - public String getDateTime() - { - SimpleDateFormat sdf = new SimpleDateFormat( "yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US ); - sdf.setTimeZone( UTC_TIME_ZONE ); - return sdf.format( new Date() ); + try + { + w = WriterFactory.newXmlWriter( doc ); + xpp3.write( w, docModel ); + getLog().debug( "Generated a default document model: " + doc.getAbsolutePath() ); + } + catch ( IOException io ) + { + getLog().debug( "Failed to write document model: " + doc.getAbsolutePath(), io ); + } + finally + { + IOUtil.close( w ); + } } } } Modified: maven/plugins/trunk/maven-pdf-plugin/src/test/java/org/apache/maven/plugins/pdf/PdfMojoTest.java URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-pdf-plugin/src/test/java/org/apache/maven/plugins/pdf/PdfMojoTest.java?rev=786524&r1=786523&r2=786524&view=diff ============================================================================== --- maven/plugins/trunk/maven-pdf-plugin/src/test/java/org/apache/maven/plugins/pdf/PdfMojoTest.java (original) +++ maven/plugins/trunk/maven-pdf-plugin/src/test/java/org/apache/maven/plugins/pdf/PdfMojoTest.java Fri Jun 19 14:48:55 2009 @@ -141,7 +141,7 @@ // ${project.developers[0].email} assertTrue( foContent.indexOf( "vsive...@apache.org ltheu...@apache.org" ) > 0 ); // ${date} - assertTrue( foContent.indexOf( new PdfMojo.DateBean().getDate() ) > 0 ); + // TODO: this might fail on NewYear's eve! :) + assertTrue( foContent.indexOf( new DateBean().getDate() ) > 0 ); } - } \ No newline at end of file