001: package org.tigris.scarab.screens;
002:
003: /* ================================================================
004: * Copyright (c) 2006 CollabNet. All rights reserved.
005: *
006: * Redistribution and use in source and binary forms, with or without
007: * modification, are permitted provided that the following conditions are
008: * met:
009: *
010: * 1. Redistributions of source code must retain the above copyright
011: * notice, this list of conditions and the following disclaimer.
012: *
013: * 2. Redistributions in binary form must reproduce the above copyright
014: * notice, this list of conditions and the following disclaimer in the
015: * documentation and/or other materials provided with the distribution.
016: *
017: * 3. The end-user documentation included with the redistribution, if
018: * any, must include the following acknowlegement: "This product includes
019: * software developed by Collab.Net <http://www.Collab.Net/>."
020: * Alternately, this acknowlegement may appear in the software itself, if
021: * and wherever such third-party acknowlegements normally appear.
022: *
023: * 4. The hosted project names must not be used to endorse or promote
024: * products derived from this software without prior written
025: * permission. For written permission, please contact info@collab.net.
026: *
027: * 5. Products derived from this software may not use the "Tigris" or
028: * "Scarab" names nor may "Tigris" or "Scarab" appear in their names without
029: * prior written permission of Collab.Net.
030: *
031: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
032: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
033: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
034: * IN NO EVENT SHALL COLLAB.NET OR ITS CONTRIBUTORS BE LIABLE FOR ANY
035: * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
036: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
037: * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
038: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
039: * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
040: * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
041: * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
042: *
043: * ====================================================================
044: *
045: * This software consists of voluntary contributions made by many
046: * individuals on behalf of Collab.Net.
047: */
048: import java.io.IOException;
049: import java.io.Writer;
050: import java.util.ArrayList;
051: import java.util.Date;
052: import java.util.Iterator;
053: import java.util.List;
054:
055: import org.apache.fulcrum.parser.ParameterParser;
056: import org.apache.fulcrum.security.util.TurbineSecurityException;
057: import org.apache.torque.TorqueException;
058: import org.apache.turbine.RunData;
059: import org.apache.turbine.TemplateContext;
060: import org.tigris.scarab.om.AttributeValue;
061: import org.tigris.scarab.om.Issue;
062: import org.tigris.scarab.om.IssueManager;
063: import org.tigris.scarab.om.MITList;
064: import org.tigris.scarab.om.Query;
065: import org.tigris.scarab.om.RModuleAttribute;
066: import org.tigris.scarab.om.RModuleUserAttribute;
067: import org.tigris.scarab.tools.ScarabLocalizationTool;
068: import org.tigris.scarab.tools.ScarabRequestTool;
069: import org.tigris.scarab.util.IteratorWithSize;
070: import org.tigris.scarab.util.ScarabConstants;
071: import org.tigris.scarab.util.ScarabLink;
072: import org.tigris.scarab.util.ScarabUtil;
073: import org.tigris.scarab.util.word.QueryResult;
074:
075: import com.sun.syndication.feed.synd.SyndContent;
076: import com.sun.syndication.feed.synd.SyndContentImpl;
077: import com.sun.syndication.feed.synd.SyndEntry;
078: import com.sun.syndication.feed.synd.SyndEntryImpl;
079: import com.sun.syndication.feed.synd.SyndFeed;
080: import com.sun.syndication.feed.synd.SyndFeedImpl;
081: import com.sun.syndication.io.FeedException;
082: import com.sun.syndication.io.SyndFeedOutput;
083: import com.workingdogs.village.DataSetException;
084:
085: /**
086: * Screen that will act just like IssueList, but will dump the results of the in-session
087: * query into a rss feed in the outputstream (no .vm template associated)
088: *
089: * @author jorgeuriarte
090: *
091: */
092: public class RSSIssueList extends Default {
093: private static final String DEFAULT_FEED_FORMAT = "atom_0.3";
094: ScarabLocalizationTool l10n = null;
095:
096: protected void doBuildTemplate(RunData data, TemplateContext context)
097: throws Exception {
098: ScarabRequestTool scarabR = getScarabRequestTool(context);
099: l10n = getLocalizationTool(context);
100: ScarabLink scarabLink = getScarabLinkTool(context);
101: ParameterParser parser = data.getParameters();
102: String feedType = parser.getString(RSSDataExport.FEED_TYPE_KEY);
103: SyndFeed feed = getQueryFeed(scarabR, scarabLink);
104: feed
105: .setFeedType((feedType == null) ? RSSDataExport.DEFAULT_FEED_FORMAT
106: : feedType);
107: Writer writer = data.getResponse().getWriter();
108: outputFilteredXml(feed, writer);
109: data.setTarget(null);
110: }
111:
112: private SyndFeed getQueryFeed(ScarabRequestTool scarabR,
113: ScarabLink scarabLink) throws Exception, TorqueException,
114: DataSetException, TurbineSecurityException {
115: Query query = scarabR.getQuery();
116: MITList mitList = query.getMITList();
117:
118: boolean showModuleName = !mitList.isSingleModule();
119: boolean showIssueType = !mitList.isSingleIssueType();
120:
121: IteratorWithSize it = scarabR.getCurrentSearchResults();
122: SyndFeed feed = new SyndFeedImpl();
123: feed.setTitle(query.getName());
124: String link = scarabLink.setAction("Search").addPathInfo("go",
125: query.getQueryId()).toString();
126: feed.setLink(link);
127: feed.setDescription(query.getDescription());
128: List entries = new ArrayList();
129: while (it.hasNext()) {
130: SyndEntry entry = new SyndEntryImpl();
131: SyndContent description = new SyndContentImpl();
132: QueryResult queryResult = (QueryResult) it.next();
133: String title = queryResult.getUniqueId();
134: if (showModuleName) {
135: title = title + " ("
136: + queryResult.getModule().getRealName() + ")";
137: }
138: if (showIssueType) {
139: title = title
140: + " ("
141: + queryResult.getRModuleIssueType()
142: .getDisplayName() + ")";
143: }
144: entry.setTitle(title);
145:
146: Issue issue = IssueManager.getInstance(Long
147: .valueOf(queryResult.getIssueId()));
148:
149: link = scarabLink.getIssueIdAbsoluteLink(issue).toString();
150: entry.setLink(link);
151:
152: Date publishedDate = null;
153: if (issue.getModifiedDate() != null) {
154: publishedDate = issue.getModifiedDate();
155: } else {
156: publishedDate = issue.getCreatedDate();
157: }
158: entry.setPublishedDate(publishedDate);
159:
160: description = new SyndContentImpl();
161: description.setType("text/html");
162: String desc = "";
163: List attributeValues = queryResult
164: .getAttributeValuesAsCSV();
165: if (null != attributeValues) {
166: Iterator avIteratorCSV = attributeValues.iterator();
167: Iterator avIterator = scarabR
168: .getRModuleUserAttributes().iterator();
169: while (avIterator.hasNext()) {
170: String value = (String) avIteratorCSV.next();
171: RModuleUserAttribute av = (RModuleUserAttribute) avIterator
172: .next();
173: String name = "";
174: if (av.isInternal()) {
175: name = av.getName(l10n);
176: } else {
177: if (mitList.isSingleModuleIssueType()) {
178: name = mitList.getModule()
179: .getRModuleAttribute(
180: av.getAttribute(),
181: mitList.getIssueType())
182: .getDisplayValue();
183: } else {
184: name = av.getAttribute().getName();
185:
186: }
187: }
188: desc = desc + "<b>" + name + ":</b>" + value
189: + "<br/>";
190: }
191: } else {
192: AttributeValue av = issue
193: .getDefaultTextAttributeValue();
194: if (av != null) {
195: RModuleAttribute rma = av.getRModuleAttribute();
196: desc = "<b>" + rma.getDisplayValue() + ":</b>"
197: + av.getValue() + "<br/>";
198: }
199: }
200:
201: description.setValue(ScarabUtil.filterNonXml(desc));
202:
203: entry.setDescription(description);
204: entries.add(entry);
205: }
206: feed.setEntries(entries);
207: feed.setFeedType(DEFAULT_FEED_FORMAT);
208: return feed;
209: }
210:
211: private ScarabLink getScarabLinkTool(TemplateContext context) {
212: return (ScarabLink) context
213: .get(ScarabConstants.SCARAB_LINK_TOOL);
214: }
215:
216: private void outputFilteredXml(SyndFeed feed, Writer writer)
217: throws IOException, FeedException {
218: SyndFeedOutput output = new SyndFeedOutput();
219: try {
220: output.output(feed, writer);
221: } catch (FeedException fe) {
222: // Will retry after filtering
223: feed.setDescription(ScarabUtil.filterNonXml(feed
224: .getDescription()));
225: output.output(feed, writer);
226: }
227: }
228: }
|