View Javadoc
1   package org.apache.maven.plugins.pdf;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.io.File;
23  import java.io.IOException;
24  import java.io.Reader;
25  import java.io.StringReader;
26  
27  import java.util.Properties;
28  
29  import org.apache.maven.doxia.document.DocumentModel;
30  import org.apache.maven.doxia.document.io.xpp3.DocumentXpp3Reader;
31  
32  import org.apache.maven.plugin.logging.Log;
33  import org.apache.maven.project.MavenProject;
34  import org.apache.maven.shared.utils.io.FileUtils;
35  import org.codehaus.plexus.interpolation.EnvarBasedValueSource;
36  import org.codehaus.plexus.interpolation.InterpolationException;
37  import org.codehaus.plexus.interpolation.Interpolator;
38  import org.codehaus.plexus.interpolation.MapBasedValueSource;
39  import org.codehaus.plexus.interpolation.ObjectBasedValueSource;
40  import org.codehaus.plexus.interpolation.RegexBasedInterpolator;
41  import org.codehaus.plexus.util.IOUtil;
42  import org.codehaus.plexus.util.ReaderFactory;
43  import org.codehaus.plexus.util.introspection.ReflectionValueExtractor;
44  import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
45  import java.util.Locale;
46  
47  /**
48   * Read and filter a DocumentModel from a document descriptor file.
49   *
50   * @author ltheussl
51   */
52  public class DocumentDescriptorReader
53  {
54      /** A MavenProject to extract additional info. */
55      private final MavenProject project;
56  
57      /** Used to log the interpolated document descriptor. */
58      private final Log log;
59  
60      private final Locale locale;
61  
62      /**
63       * Constructor.
64       */
65      public DocumentDescriptorReader()
66      {
67          this( null, null, null );
68      }
69  
70      /**
71       * Constructor.
72       *
73       * @param project may be null.
74       */
75      public DocumentDescriptorReader( final MavenProject project )
76      {
77          this( project, null, null );
78      }
79  
80      /**
81       * Constructor.
82       *
83       * @param project may be null.
84       * @param log may be null.
85       */
86      public DocumentDescriptorReader( final MavenProject project, final Log log, final Locale locale )
87      {
88          this.project = project;
89          this.log = log;
90          this.locale = locale;
91      }
92  
93      /**
94       * Read and filter the <code>docDescriptor</code> file.
95       *
96       * @param docDescriptor not null, corresponding to non-localized descriptor file.
97       * @return a DocumentModel instance.
98       * @throws XmlPullParserException if an error occurs during parsing.
99       * @throws IOException if an error occurs during reading.
100      */
101     public DocumentModel readAndFilterDocumentDescriptor( File docDescriptor )
102         throws XmlPullParserException, IOException
103     {
104         if ( locale != null )
105         {
106             String descriptorFilename = docDescriptor.getName();
107             String localized = FileUtils.removeExtension( descriptorFilename ) + '_' + locale.getLanguage() + '.'
108                 + FileUtils.getExtension( descriptorFilename );
109             File localizedDocDescriptor = new File( docDescriptor.getParentFile(), localized );
110 
111             if ( localizedDocDescriptor.exists() )
112             {
113                 docDescriptor = localizedDocDescriptor;
114             }
115         }
116 
117         try
118         {
119             // System properties
120             final Properties filterProperties = System.getProperties();
121             // Project properties
122             if ( project != null && project.getProperties() != null )
123             {
124                 filterProperties.putAll( project.getProperties() );
125             }
126 
127             final Interpolator interpolator = new RegexBasedInterpolator();
128             interpolator.addValueSource( new MapBasedValueSource( filterProperties ) );
129             interpolator.addValueSource( new EnvarBasedValueSource() );
130             interpolator.addValueSource( new ObjectBasedValueSource( project )
131             {
132                 /** {@inheritDoc} */
133                 public Object getValue( final String expression )
134                 {
135                     try
136                     {
137                         return ReflectionValueExtractor.evaluate( expression, project );
138                     }
139                     catch ( Exception e )
140                     {
141                         addFeedback( "Failed to extract '" + expression + "' from: " + project, e );
142                     }
143 
144                     return null;
145                 }
146             } );
147 
148             final DateBean bean = new DateBean();
149             interpolator.addValueSource( new ObjectBasedValueSource( bean ) );
150 
151             try ( Reader reader = ReaderFactory.newXmlReader( docDescriptor ) )
152             {
153                 final String interpolatedDoc = interpolator.interpolate( IOUtil.toString( reader ) );
154 
155                 if ( log != null && log.isDebugEnabled() )
156                 {
157                     log.debug( "Interpolated document descriptor ("
158                                    + docDescriptor.getAbsolutePath() + ")\n" + interpolatedDoc );
159                 }
160 
161                 // No Strict
162                 return new DocumentXpp3Reader().read( new StringReader( interpolatedDoc ), false );
163             }
164         }
165         catch ( InterpolationException e )
166         {
167             throw new IOException( "Error interpolating document descriptor", e );
168         }
169     }
170 }