1 /*******************************************************************************
2 * Copyright � Igor Barma, Alexandre Desoubeaux, Christian Martel, Eric Brun, Mathieu Amblard, Gwenael Gevet, Pierre Guillot, 2012
3 * Copyright Alexandre Desoubeaux, Christian Martel, Cedric Lecarpentier, Alexandre Lefevre, Marc Salvat 2014-2016
4 * Copyright Alexandre Desoubeaux, Christian Martel, Cedric Lecarpentier, Marc Salvat, Marc Suarez, Harifetra Ramamonjy 2017
6 * This file is part of the work and learning management system Pentila Nero.
8 * Pentila Nero is free software. You can redistribute it and/or modify since
9 * you respect the terms of either (at least one of the both license) :
10 * - under the terms of the GNU Affero General Public License as
11 * published by the Free Software Foundation, either version 3 of the
12 * License, or (at your option) any later version.
13 * - the CeCILL-C as published by CeCILL-C; either version 1 of the
14 * License, or any later version
15 * - the GNU Lesser General Public License as published by the
16 * Free Software Foundation, either version 3 of the license,
17 * or (at your option) any later version.
19 * There are special exceptions to the terms and conditions of the
20 * licenses as they are applied to this software. View the full text of
21 * the exception in file LICENSE-PROJECT.txt in the directory of this software
24 * Pentila Nero is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * Licenses for more details.
29 * You should have received a copy of the GNU Affero General Public License
30 * and the CeCILL-C and the GNU Lesser General Public License along with
31 * Pentila Nero. If not, see :
32 * <http://www.gnu.org/licenses/> and
33 * <http://www.cecill.info/licences.fr.html>.
34 ******************************************************************************/
35 package com.pentila.entSavoie.blog.action;
37 import java.io.ByteArrayInputStream;
38 import java.io.ByteArrayOutputStream;
39 import java.io.InputStream;
40 import java.text.DateFormat;
41 import java.text.SimpleDateFormat;
42 import java.util.ArrayList;
43 import java.util.Collections;
44 import java.util.Comparator;
45 import java.util.Date;
46 import java.util.List;
47 import java.util.Locale;
49 import javax.servlet.http.HttpServletRequest;
50 import javax.servlet.http.HttpServletResponse;
51 import javax.xml.parsers.DocumentBuilder;
52 import javax.xml.parsers.DocumentBuilderFactory;
53 import javax.xml.parsers.ParserConfigurationException;
54 import javax.xml.transform.Result;
55 import javax.xml.transform.Transformer;
56 import javax.xml.transform.TransformerException;
57 import javax.xml.transform.TransformerFactory;
58 import javax.xml.transform.dom.DOMSource;
59 import javax.xml.transform.stream.StreamResult;
61 import org.apache.struts.action.Action;
62 import org.apache.struts.action.ActionForm;
63 import org.apache.struts.action.ActionForward;
64 import org.apache.struts.action.ActionMapping;
65 import org.w3c.dom.Document;
66 import org.w3c.dom.Element;
68 import com.liferay.portal.kernel.util.FileUtil;
69 import com.liferay.portal.kernel.util.HtmlUtil;
70 import com.liferay.portal.kernel.util.HttpUtil;
71 import com.liferay.portal.kernel.util.MimeTypesOverrideUtil;
72 import com.liferay.portal.kernel.util.ParamUtil;
73 import com.liferay.portal.kernel.util.WebKeys;
74 import com.liferay.portal.model.User;
75 import com.liferay.portal.service.UserLocalServiceUtil;
76 import com.liferay.portal.theme.ThemeDisplay;
77 import com.liferay.portal.util.PortalUtil;
78 import com.pentila.entSavoie.blog.model.BlogChannel;
79 import com.pentila.entSavoie.blog.model.BlogItem;
80 import com.pentila.entSavoie.blog.service.BlogChannelLocalServiceUtil;
81 import com.pentila.entSavoie.blog.service.BlogItemLocalServiceUtil;
82 import com.pentila.entSavoie.search.util.IndexerUtil;
83 import com.pentila.entSavoie.servlet.ServletResponseServiceUtil;
84 import com.pentila.entSavoie.utils.ENTMainUtilsLocalServiceUtil;
86 public class GetBlogRssFileAction extends Action {
88 static DateFormat formatter = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.ENGLISH);
90 public ActionForward execute(final ActionMapping mapping, final ActionForm form,
91 final HttpServletRequest request, final HttpServletResponse response)
94 long channelId = ParamUtil.getLong(request, "channelId");
95 long categoryId = ParamUtil.getLong(request, "categoryId");
96 BlogChannel channel = BlogChannelLocalServiceUtil.getBlogChannel(channelId);
97 long companyId = UserLocalServiceUtil.getUser(channel.getUserId()).getCompanyId();
98 getFile(companyId, channelId, categoryId, response, request);
101 catch (Exception e) {
103 PortalUtil.sendError(e, request, response);
109 protected void getFile(final long companyId, final long channelId, long categoryId,
110 final HttpServletResponse response, final HttpServletRequest request)
113 ThemeDisplay themeDisplay = (ThemeDisplay) request.getAttribute(WebKeys.THEME_DISPLAY);
115 InputStream is = null;
118 BlogChannel blogChannel = BlogChannelLocalServiceUtil.getBlogChannel(channelId);
119 boolean channelSubscribe = categoryId == 0 || categoryId == channelId;
120 String categoryParameter = channelSubscribe?"":"&categoryId=" + categoryId;
121 User user = UserLocalServiceUtil.getUser(blogChannel.getUserId());
122 String fullName = user.getFullName();
123 String emailAdress = user.getEmailAddress();
125 //Creation du fichier xml
126 DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
127 DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
129 Document doc = docBuilder.newDocument();
130 Element rootElement = doc.createElement("rss");
131 rootElement.setAttribute("version", "2.0");
132 rootElement.setAttribute("xmlns:content", "http://purl.org/rss/1.0/modules/content/");
133 rootElement.setAttribute("xmlns:wfw", "http://wellformedweb.org/CommentAPI/");
134 rootElement.setAttribute("xmlns:dc", "http://purl.org/dc/elements/1.1/");
135 rootElement.setAttribute("xmlns:atom", "http://www.w3.org/2005/Atom");
136 rootElement.setAttribute("xmlns:sy", "http://purl.org/rss/1.0/modules/syndication/");
137 rootElement.setAttribute("xmlns:itunes", "http://www.itunes.com/dtds/podcast-1.0.dtd");
138 rootElement.setAttribute("xml:lang", "fr-FR");
139 doc.appendChild(rootElement);
142 Element channel = doc.createElement("channel");
143 rootElement.appendChild(channel);
146 Element title = doc.createElement("title");
147 title.appendChild(doc.createTextNode(blogChannel.getTitle()));
148 channel.appendChild(title);
150 // description channel
151 Element description = doc.createElement("description");
152 description.appendChild(doc.createTextNode(IndexerUtil.normalizeString(HtmlUtil.extractText(blogChannel.getDescription()))));
153 channel.appendChild(description);
156 String imageFileName = FileUtil.getShortFileName(blogChannel.getImageFile(themeDisplay.getCompanyId()));
157 if (!imageFileName.isEmpty()) {
159 Element image = doc.createElement("image");
160 channel.appendChild(image);
162 Element urlImage = doc.createElement("url");
163 String urlImageString = PortalUtil.getPortalProperties().getProperty("absolute.url") + themeDisplay.getPathMain() + "/blog/get_channel_file?channelId=" + blogChannel.getChannelId() + "&fileName=" + HttpUtil.encodeURL(imageFileName) + "&fileType=image";
164 urlImage.appendChild(doc.createTextNode(urlImageString));
165 image.appendChild(urlImage);
167 Element titleImage = doc.createElement("title");
168 titleImage.appendChild(doc.createTextNode(blogChannel.getTitle()));
169 image.appendChild(titleImage);
171 Element linkImage = doc.createElement("link");
172 String linkImageString = ENTMainUtilsLocalServiceUtil.getPublicBlogUrl(companyId) + "?channelId=" + blogChannel.getChannelId() + categoryParameter;
173 linkImage.appendChild(doc.createTextNode(linkImageString));
174 image.appendChild(linkImage);
176 String urlItunesImageString = ENTMainUtilsLocalServiceUtil.getPublicFrontBlogUrl(companyId) + "get_channel_file/channelId/" + blogChannel.getChannelId() + "/image/" + HttpUtil.encodeURL(imageFileName);
177 Element itunesImage = doc.createElement("itunes:image");
178 itunesImage.setAttribute("href", urlItunesImageString);
179 channel.appendChild(itunesImage);
183 Element link = doc.createElement("link");
184 String linkString = ENTMainUtilsLocalServiceUtil.getPublicBlogUrl(companyId) + "?channelId=" + blogChannel.getChannelId() + categoryParameter;
185 link.appendChild(doc.createTextNode(linkString));
186 channel.appendChild(link);
189 Element atomLink = doc.createElement("atom:link");
190 atomLink.setAttribute("href", linkString);
191 atomLink.setAttribute("rel", "self");
192 atomLink.setAttribute("type", "application/rss+xml");
193 channel.appendChild(atomLink);
196 Element lastBuildDate = doc.createElement("lastBuildDate");
197 lastBuildDate.appendChild(doc.createTextNode(formatter.format(blogChannel.getLastBuildDate())));
198 channel.appendChild(lastBuildDate);
201 Element itunesCategory = doc.createElement("itunes:category");
202 itunesCategory.setAttribute("text", "Education");
203 channel.appendChild(itunesCategory);
206 Element itunesExplicit = doc.createElement("itunes:explicit");
207 itunesExplicit.appendChild(doc.createTextNode("No"));
208 channel.appendChild(itunesExplicit);
211 Element itunesOwner = doc.createElement("itunes:owner");
212 Element itunesName = doc.createElement("itunes:name");
213 itunesName.appendChild(doc.createTextNode(fullName));
214 itunesOwner.appendChild(itunesName);
215 Element itunesEmail = doc.createElement("itunes:email");
216 itunesEmail.appendChild(doc.createTextNode(emailAdress));
217 itunesOwner.appendChild(itunesEmail);
218 channel.appendChild(itunesOwner);
220 // Liste des items du channel
221 List<BlogItem> lstBlogItem = new ArrayList<BlogItem>();
222 if(channelSubscribe){
223 lstBlogItem.addAll(BlogItemLocalServiceUtil.getBlogItemByChannelId(channelId));
225 lstBlogItem.addAll(BlogItemLocalServiceUtil.getBlogItemByCategoryId(categoryId));
228 // Tri des items du plus recent au plus ancien
229 Collections.sort(lstBlogItem, new Comparator<BlogItem>() {
230 public int compare(BlogItem item1, BlogItem item2) {
231 Long pubDate1 = item1.getPubDate().getTime();
232 Long pubDate2 = item2.getPubDate().getTime();
233 return pubDate2.compareTo(pubDate1);
238 for (final BlogItem item : lstBlogItem) {
240 if (!item.getPubDate().after(new Date())) {
242 Element itemEl = doc.createElement("item");
243 channel.appendChild(itemEl);
246 Element titleItem = doc.createElement("title");
247 titleItem.appendChild(doc.createTextNode(item.getTitle()));
248 itemEl.appendChild(titleItem);
251 Element descriptionItem = doc.createElement("description");
252 String descriptionString = IndexerUtil.normalizeString(HtmlUtil.extractText(item.getDescription())) + "\n";
253 String[] attachementsFiles = item.getAttachmentsFiles(item.getCompanyId());
254 if (attachementsFiles.length > 0) {
255 descriptionString += ".\nCe billet comporte des pi\u00e8ces jointes : ";
256 for (int k = 0; k < attachementsFiles.length; k++) {
257 descriptionString += FileUtil.getShortFileName(attachementsFiles[k]) + ", ";
259 descriptionString = descriptionString.substring(0, descriptionString.lastIndexOf(",")) + ".";
260 String urlBilletString = ENTMainUtilsLocalServiceUtil.getPublicBlogUrl(companyId) + "?channelId=" + blogChannel.getChannelId() + "&billetId=" + item.getItemId();
261 descriptionString += "\nPour les t\u00e9l\u00e9charger veuillez vous rendre \u00e0 cette adresse : <a href = \"" + urlBilletString + "\">" + urlBilletString + "</a>";
263 descriptionItem.appendChild(doc.createTextNode(descriptionString));
264 itemEl.appendChild(descriptionItem);
267 Element pubDateItem = doc.createElement("pubDate");
268 pubDateItem.appendChild(doc.createTextNode(formatter.format(item.getPubDate())));
269 itemEl.appendChild(pubDateItem);
272 Element authorItem = doc.createElement("author");
273 authorItem.appendChild(doc.createTextNode(emailAdress + " (" + fullName + ")"));
274 itemEl.appendChild(authorItem);
277 String mediaOriginalFileName = item.getMediaOriginalFile(item.getCompanyId());
278 int size = FileUtil.getExtension(mediaOriginalFileName).length();
279 String mediaFileName = FileUtil.getShortFileName(mediaOriginalFileName);
280 if (!mediaFileName.equals("")) {
281 Element mediaItem = doc.createElement("enclosure");
282 mediaItem.setAttribute("url", ENTMainUtilsLocalServiceUtil.getPublicFrontBlogUrl(companyId) + "get_item_file/itemId/" + item.getItemId() + "/mediaOriginal/" + HttpUtil.encodeURL(mediaFileName));
283 mediaItem.setAttribute("length", String.valueOf(size));
284 mediaItem.setAttribute("type", MimeTypesOverrideUtil.getContentType(mediaFileName));
285 itemEl.appendChild(mediaItem);
289 Element linkItem = doc.createElement("link");
290 String linkItemString = ENTMainUtilsLocalServiceUtil.getPublicBlogUrl(companyId) + "?channelId=" + blogChannel.getChannelId() + "&billetId=" + item.getItemId();
291 linkItem.appendChild(doc.createTextNode(linkItemString));
292 itemEl.appendChild(linkItem);
295 String imageItemFileName = FileUtil.getShortFileName(item.getImageFile(item.getCompanyId()));
296 if(!imageItemFileName.isEmpty()){
297 String urlItunesImageString = ENTMainUtilsLocalServiceUtil.getPublicFrontBlogUrl(companyId) + "get_item_file/itemId/" + item.getItemId() + "/image/" + HttpUtil.encodeURL(imageItemFileName);
298 Element itunesImage = doc.createElement("itunes:image");
299 itunesImage.setAttribute("href", urlItunesImageString);
300 itemEl.appendChild(itunesImage);
304 Element guidItem = doc.createElement("guid");
305 guidItem.appendChild(doc.createTextNode(linkItemString));
306 itemEl.appendChild(guidItem);
315 // Ecrit le contenu dans un fichier xml
316 TransformerFactory transformerFactory = TransformerFactory.newInstance();
317 Transformer transformer = transformerFactory.newTransformer();
318 DOMSource source = new DOMSource(doc);
319 ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
320 Result outputTarget = new StreamResult(outputStream);
321 transformer.transform(source, outputTarget);
322 byte[] byteArray = outputStream.toByteArray();
323 is = new ByteArrayInputStream(byteArray);
325 int contentLength = byteArray.length;
326 ServletResponseServiceUtil.sendFile(response, channelId + ".xml", is, contentLength, "application/rss+xml", "inline");
328 } catch (final ParserConfigurationException pce) {
329 pce.printStackTrace();
330 } catch (final TransformerException tfe) {
331 tfe.printStackTrace();