1 package org.apache.velocity.site.news.macro;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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
52
53
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
175
176
177
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 }