View Javadoc

1   package org.apache.velocity.site.news.macro;
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.lang.reflect.Method;
24  import java.util.ListIterator;
25  import java.util.Locale;
26  import java.util.ResourceBundle;
27  
28  import org.apache.maven.doxia.macro.AbstractMacro;
29  import org.apache.maven.doxia.macro.MacroExecutionException;
30  import org.apache.maven.doxia.macro.MacroRequest;
31  import org.apache.maven.doxia.parser.Parser;
32  import org.apache.maven.doxia.sink.Sink;
33  import org.apache.velocity.site.news.NewsBlockGenerator;
34  import org.apache.velocity.site.news.NewsReport;
35  import org.apache.velocity.site.news.VelocityNewsException;
36  import org.apache.velocity.site.news.VelocityNewsUtils;
37  import org.apache.velocity.site.news.model.Item;
38  import org.apache.velocity.site.news.model.NewsManager;
39  import org.apache.velocity.site.news.model.NewsModel;
40  import org.apache.velocity.site.news.plugin.VelocityNewsPlugin;
41  import org.apache.velocity.site.plexus.PlexusKludgeException;
42  import org.apache.velocity.site.plexus.PlexusKludgeUtils;
43  import org.codehaus.plexus.PlexusConstants;
44  import org.codehaus.plexus.PlexusContainer;
45  import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
46  import org.codehaus.plexus.context.Context;
47  import org.codehaus.plexus.context.ContextException;
48  import org.codehaus.plexus.personality.plexus.lifecycle.phase.Contextualizable;
49  
50  /**
51   * apt usage: %{news}
52   *
53   * @plexus.component role="org.apache.maven.doxia.macro.Macro" role-hint="news"
54   */
55  public class VelocityNewsMacro extends AbstractMacro implements Contextualizable
56  {
57  
58      private PlexusContainer container = null;
59  
60      public void contextualize(final Context context) throws ContextException
61      {
62          this.container = (PlexusContainer) context.get(PlexusConstants.PLEXUS_KEY);
63      }
64  
65      public void execute(final Sink sink, final MacroRequest request) throws MacroExecutionException
66      {
67  
68          try
69          {
70              int count = Integer.parseInt(getParameter(request, "count", "5"));
71              generateNewsBlock(sink, count);
72  
73          }
74          catch (VelocityNewsException vne)
75          {
76              throw new MacroExecutionException("While executing news macro: ", vne);
77          }
78      }
79  
80      protected String getParameter(final MacroRequest request, final String field, final String defaultValue)
81      {
82          String value = (String) request.getParameter(field);
83          return value != null ? value : defaultValue;
84      }
85  
86      protected void generateNewsBlock(final Sink sink, final int maxCount) throws VelocityNewsException
87      {
88  
89          try
90          {
91  
92              Object newsManagerRef = getNewsManager();
93  
94              Method newsFileNameMethod = newsManagerRef.getClass().getMethod(NewsManager.NEWS_FILE_NAME_METHOD, new Class[] {});
95              String newsFileName = (String) newsFileNameMethod.invoke(newsManagerRef, new Object[] {});
96  
97              Method newsSiteDirectoryMethod = newsManagerRef.getClass().getMethod(NewsManager.NEWS_SITE_DIRECTORY_METHOD,
98                      new Class[] {});
99              File siteDirectory = (File) newsSiteDirectoryMethod.invoke(newsManagerRef, new Object[] {});
100 
101             final NewsManager newsManager = new NewsManager();
102             newsManager.load(siteDirectory, newsFileName);
103 
104             NewsBlockGenerator newsBlockGenerator = new NewsBlockGenerator(new NewsReport()
105             {
106 
107                 private Parser aptParser = null;
108 
109                 public Sink getSink()
110                 {
111                     return sink;
112                 }
113 
114                 public Parser getAptParser() throws VelocityNewsException
115                 {
116                     if (aptParser == null)
117                     {
118                         try
119                         {
120                             aptParser = (Parser) container.lookup(Parser.ROLE, "apt");
121                         }
122                         catch (ComponentLookupException cle)
123                         {
124                             throw new VelocityNewsException(cle);
125                         }
126                     }
127                     return aptParser;
128                 }
129 
130                 public ResourceBundle getBundle(final Locale locale)
131                 {
132                     return ResourceBundle.getBundle("velocity-news-report", locale);
133                 }
134 
135                 public String getOutputName()
136                 {
137                     try
138                     {
139                         return (String) newsManager.getNewsFileName();
140                     }
141                     catch (RuntimeException re)
142                     {
143                         throw re;
144                     }
145                     catch (Exception e)
146                     {
147                         throw new IllegalStateException("Could not retrieve page name from model!");
148                     }
149                 }
150 
151             }, Locale.ENGLISH);
152 
153             NewsModel newsModel = newsManager.getNewsModel();
154 
155             for (ListIterator it = VelocityNewsUtils.sortItemsByReverseDate(newsModel.getItems()).listIterator(); it.hasNext()
156                     && it.nextIndex() < maxCount;)
157             {
158                 Item newsItem = (Item) it.next();
159                 newsBlockGenerator.displayItem(newsItem);
160             }
161 
162         }
163         catch (RuntimeException re)
164         {
165             throw re;
166         }
167         catch (Exception e)
168         {
169             throw new IllegalStateException("Could not retrieve page name from model!");
170         }
171     }
172 
173     /**
174      * Returns the News Manager from the Plugin.
175      *
176      * @return A {@link DoxiaVelocityContextFactory} instance that generates
177      *         {@link VelocityContext} objects for the render process.
178      */
179     private Object getNewsManager() throws VelocityNewsException
180     {
181         try
182         {
183             PlexusContainer velocityContainer = PlexusKludgeUtils.lookupContainer(container,
184                     VelocityNewsPlugin.CONTAINER_LOOKUP_NAME);
185             return velocityContainer.lookup(NewsManager.ROLE);
186         }
187         catch (PlexusKludgeException pke)
188         {
189             throw new VelocityNewsException("While retrieving News Manager: ", pke);
190         }
191         catch (ComponentLookupException cle)
192         {
193             throw new VelocityNewsException("While retrieving News Manager: ", cle);
194         }
195     }
196 }