--- /dev/null
+/*******************************************************************************
+ * Copyright � Igor Barma, Alexandre Desoubeaux, Christian Martel, Eric Brun, Mathieu Amblard, Gwenael Gevet, Pierre Guillot, 2012
+ * Copyright Alexandre Desoubeaux, Christian Martel, Cedric Lecarpentier, Alexandre Lefevre, Marc Salvat 2014-2016
+ * Copyright Alexandre Desoubeaux, Christian Martel, Cedric Lecarpentier, Marc Salvat, Marc Suarez, Harifetra Ramamonjy 2017
+ *
+ * This file is part of the work and learning management system Pentila Nero.
+ *
+ * Pentila Nero is free software. You can redistribute it and/or modify since
+ * you respect the terms of either (at least one of the both license) :
+ * - under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ * - the CeCILL-C as published by CeCILL-C; either version 1 of the
+ * License, or any later version
+ * - the GNU Lesser General Public License as published by the
+ * Free Software Foundation, either version 3 of the license,
+ * or (at your option) any later version.
+ *
+ * There are special exceptions to the terms and conditions of the
+ * licenses as they are applied to this software. View the full text of
+ * the exception in file LICENSE-PROJECT.txt in the directory of this software
+ * distribution.
+ *
+ * Pentila Nero is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * Licenses for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * and the CeCILL-C and the GNU Lesser General Public License along with
+ * Pentila Nero. If not, see :
+ * <http://www.gnu.org/licenses/> and
+ * <http://www.cecill.info/licences.fr.html>.
+ ******************************************************************************/
+package com.pentila.entSavoie.blog.action;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.List;
+import java.util.Locale;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.Result;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.apache.struts.action.Action;
+import org.apache.struts.action.ActionForm;
+import org.apache.struts.action.ActionForward;
+import org.apache.struts.action.ActionMapping;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import com.liferay.portal.kernel.util.FileUtil;
+import com.liferay.portal.kernel.util.HtmlUtil;
+import com.liferay.portal.kernel.util.HttpUtil;
+import com.liferay.portal.kernel.util.MimeTypesOverrideUtil;
+import com.liferay.portal.kernel.util.ParamUtil;
+import com.liferay.portal.kernel.util.WebKeys;
+import com.liferay.portal.model.User;
+import com.liferay.portal.service.UserLocalServiceUtil;
+import com.liferay.portal.theme.ThemeDisplay;
+import com.liferay.portal.util.PortalUtil;
+import com.pentila.entSavoie.blog.model.BlogChannel;
+import com.pentila.entSavoie.blog.model.BlogItem;
+import com.pentila.entSavoie.blog.service.BlogChannelLocalServiceUtil;
+import com.pentila.entSavoie.blog.service.BlogItemLocalServiceUtil;
+import com.pentila.entSavoie.search.util.IndexerUtil;
+import com.pentila.entSavoie.servlet.ServletResponseServiceUtil;
+import com.pentila.entSavoie.utils.ENTMainUtilsLocalServiceUtil;
+
+public class GetBlogRssFileAction extends Action {
+
+ static DateFormat formatter = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.ENGLISH);
+
+ public ActionForward execute(final ActionMapping mapping, final ActionForm form,
+ final HttpServletRequest request, final HttpServletResponse response)
+ throws Exception {
+ try {
+ long channelId = ParamUtil.getLong(request, "channelId");
+ long categoryId = ParamUtil.getLong(request, "categoryId");
+ BlogChannel channel = BlogChannelLocalServiceUtil.getBlogChannel(channelId);
+ long companyId = UserLocalServiceUtil.getUser(channel.getUserId()).getCompanyId();
+ getFile(companyId, channelId, categoryId, response, request);
+ return null;
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ PortalUtil.sendError(e, request, response);
+
+ return null;
+ }
+ }
+
+ protected void getFile(final long companyId, final long channelId, long categoryId,
+ final HttpServletResponse response, final HttpServletRequest request)
+ throws Exception {
+
+ ThemeDisplay themeDisplay = (ThemeDisplay) request.getAttribute(WebKeys.THEME_DISPLAY);
+
+ InputStream is = null;
+
+ try {
+ BlogChannel blogChannel = BlogChannelLocalServiceUtil.getBlogChannel(channelId);
+ boolean channelSubscribe = categoryId == 0 || categoryId == channelId;
+ String categoryParameter = channelSubscribe?"":"&categoryId=" + categoryId;
+ User user = UserLocalServiceUtil.getUser(blogChannel.getUserId());
+ String fullName = user.getFullName();
+ String emailAdress = user.getEmailAddress();
+
+ //Creation du fichier xml
+ DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
+ DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
+
+ Document doc = docBuilder.newDocument();
+ Element rootElement = doc.createElement("rss");
+ rootElement.setAttribute("version", "2.0");
+ rootElement.setAttribute("xmlns:content", "http://purl.org/rss/1.0/modules/content/");
+ rootElement.setAttribute("xmlns:wfw", "http://wellformedweb.org/CommentAPI/");
+ rootElement.setAttribute("xmlns:dc", "http://purl.org/dc/elements/1.1/");
+ rootElement.setAttribute("xmlns:atom", "http://www.w3.org/2005/Atom");
+ rootElement.setAttribute("xmlns:sy", "http://purl.org/rss/1.0/modules/syndication/");
+ rootElement.setAttribute("xmlns:itunes", "http://www.itunes.com/dtds/podcast-1.0.dtd");
+ rootElement.setAttribute("xml:lang", "fr-FR");
+ doc.appendChild(rootElement);
+
+ // channel
+ Element channel = doc.createElement("channel");
+ rootElement.appendChild(channel);
+
+ // title channel
+ Element title = doc.createElement("title");
+ title.appendChild(doc.createTextNode(blogChannel.getTitle()));
+ channel.appendChild(title);
+
+ // description channel
+ Element description = doc.createElement("description");
+ description.appendChild(doc.createTextNode(IndexerUtil.normalizeString(HtmlUtil.extractText(blogChannel.getDescription()))));
+ channel.appendChild(description);
+
+ // image channel
+ String imageFileName = FileUtil.getShortFileName(blogChannel.getImageFile(themeDisplay.getCompanyId()));
+ if (!imageFileName.isEmpty()) {
+
+ Element image = doc.createElement("image");
+ channel.appendChild(image);
+
+ Element urlImage = doc.createElement("url");
+ String urlImageString = PortalUtil.getPortalProperties().getProperty("absolute.url") + themeDisplay.getPathMain() + "/blog/get_channel_file?channelId=" + blogChannel.getChannelId() + "&fileName=" + HttpUtil.encodeURL(imageFileName) + "&fileType=image";
+ urlImage.appendChild(doc.createTextNode(urlImageString));
+ image.appendChild(urlImage);
+
+ Element titleImage = doc.createElement("title");
+ titleImage.appendChild(doc.createTextNode(blogChannel.getTitle()));
+ image.appendChild(titleImage);
+
+ Element linkImage = doc.createElement("link");
+ String linkImageString = ENTMainUtilsLocalServiceUtil.getPublicBlogUrl(companyId) + "?channelId=" + blogChannel.getChannelId() + categoryParameter;
+ linkImage.appendChild(doc.createTextNode(linkImageString));
+ image.appendChild(linkImage);
+
+ String urlItunesImageString = ENTMainUtilsLocalServiceUtil.getPublicFrontBlogUrl(companyId) + "get_channel_file/channelId/" + blogChannel.getChannelId() + "/image/" + HttpUtil.encodeURL(imageFileName);
+ Element itunesImage = doc.createElement("itunes:image");
+ itunesImage.setAttribute("href", urlItunesImageString);
+ channel.appendChild(itunesImage);
+ }
+
+ // link channel
+ Element link = doc.createElement("link");
+ String linkString = ENTMainUtilsLocalServiceUtil.getPublicBlogUrl(companyId) + "?channelId=" + blogChannel.getChannelId() + categoryParameter;
+ link.appendChild(doc.createTextNode(linkString));
+ channel.appendChild(link);
+
+ // atom:link
+ Element atomLink = doc.createElement("atom:link");
+ atomLink.setAttribute("href", linkString);
+ atomLink.setAttribute("rel", "self");
+ atomLink.setAttribute("type", "application/rss+xml");
+ channel.appendChild(atomLink);
+
+ // last build date
+ Element lastBuildDate = doc.createElement("lastBuildDate");
+ lastBuildDate.appendChild(doc.createTextNode(formatter.format(blogChannel.getLastBuildDate())));
+ channel.appendChild(lastBuildDate);
+
+ // itunes:category
+ Element itunesCategory = doc.createElement("itunes:category");
+ itunesCategory.setAttribute("text", "Education");
+ channel.appendChild(itunesCategory);
+
+ // itunes:explicit
+ Element itunesExplicit = doc.createElement("itunes:explicit");
+ itunesExplicit.appendChild(doc.createTextNode("No"));
+ channel.appendChild(itunesExplicit);
+
+ // itunes:owner
+ Element itunesOwner = doc.createElement("itunes:owner");
+ Element itunesName = doc.createElement("itunes:name");
+ itunesName.appendChild(doc.createTextNode(fullName));
+ itunesOwner.appendChild(itunesName);
+ Element itunesEmail = doc.createElement("itunes:email");
+ itunesEmail.appendChild(doc.createTextNode(emailAdress));
+ itunesOwner.appendChild(itunesEmail);
+ channel.appendChild(itunesOwner);
+
+ // Liste des items du channel
+ List<BlogItem> lstBlogItem = new ArrayList<BlogItem>();
+ if(channelSubscribe){
+ lstBlogItem.addAll(BlogItemLocalServiceUtil.getBlogItemByChannelId(channelId));
+ } else {
+ lstBlogItem.addAll(BlogItemLocalServiceUtil.getBlogItemByCategoryId(categoryId));
+ }
+
+ // Tri des items du plus recent au plus ancien
+ Collections.sort(lstBlogItem, new Comparator<BlogItem>() {
+ public int compare(BlogItem item1, BlogItem item2) {
+ Long pubDate1 = item1.getPubDate().getTime();
+ Long pubDate2 = item2.getPubDate().getTime();
+ return pubDate2.compareTo(pubDate1);
+ }
+ });
+
+ int nbItems = 20;
+ for (final BlogItem item : lstBlogItem) {
+ if (nbItems > 0) {
+ if (!item.getPubDate().after(new Date())) {
+ // item
+ Element itemEl = doc.createElement("item");
+ channel.appendChild(itemEl);
+
+ // title item
+ Element titleItem = doc.createElement("title");
+ titleItem.appendChild(doc.createTextNode(item.getTitle()));
+ itemEl.appendChild(titleItem);
+
+ // description item
+ Element descriptionItem = doc.createElement("description");
+ String descriptionString = IndexerUtil.normalizeString(HtmlUtil.extractText(item.getDescription())) + "\n";
+ String[] attachementsFiles = item.getAttachmentsFiles(item.getCompanyId());
+ if (attachementsFiles.length > 0) {
+ descriptionString += ".\nCe billet comporte des pi\u00e8ces jointes : ";
+ for (int k = 0; k < attachementsFiles.length; k++) {
+ descriptionString += FileUtil.getShortFileName(attachementsFiles[k]) + ", ";
+ }
+ descriptionString = descriptionString.substring(0, descriptionString.lastIndexOf(",")) + ".";
+ String urlBilletString = ENTMainUtilsLocalServiceUtil.getPublicBlogUrl(companyId) + "?channelId=" + blogChannel.getChannelId() + "&billetId=" + item.getItemId();
+ descriptionString += "\nPour les t\u00e9l\u00e9charger veuillez vous rendre \u00e0 cette adresse : <a href = \"" + urlBilletString + "\">" + urlBilletString + "</a>";
+ }
+ descriptionItem.appendChild(doc.createTextNode(descriptionString));
+ itemEl.appendChild(descriptionItem);
+
+ // pubDate item
+ Element pubDateItem = doc.createElement("pubDate");
+ pubDateItem.appendChild(doc.createTextNode(formatter.format(item.getPubDate())));
+ itemEl.appendChild(pubDateItem);
+
+ // author item
+ Element authorItem = doc.createElement("author");
+ authorItem.appendChild(doc.createTextNode(emailAdress + " (" + fullName + ")"));
+ itemEl.appendChild(authorItem);
+
+ // enclosure item
+ String mediaOriginalFileName = item.getMediaOriginalFile(item.getCompanyId());
+ int size = FileUtil.getExtension(mediaOriginalFileName).length();
+ String mediaFileName = FileUtil.getShortFileName(mediaOriginalFileName);
+ if (!mediaFileName.equals("")) {
+ Element mediaItem = doc.createElement("enclosure");
+ mediaItem.setAttribute("url", ENTMainUtilsLocalServiceUtil.getPublicFrontBlogUrl(companyId) + "get_item_file/itemId/" + item.getItemId() + "/mediaOriginal/" + HttpUtil.encodeURL(mediaFileName));
+ mediaItem.setAttribute("length", String.valueOf(size));
+ mediaItem.setAttribute("type", MimeTypesOverrideUtil.getContentType(mediaFileName));
+ itemEl.appendChild(mediaItem);
+ }
+
+ // link item
+ Element linkItem = doc.createElement("link");
+ String linkItemString = ENTMainUtilsLocalServiceUtil.getPublicBlogUrl(companyId) + "?channelId=" + blogChannel.getChannelId() + "&billetId=" + item.getItemId();
+ linkItem.appendChild(doc.createTextNode(linkItemString));
+ itemEl.appendChild(linkItem);
+
+ // image item
+ String imageItemFileName = FileUtil.getShortFileName(item.getImageFile(item.getCompanyId()));
+ if(!imageItemFileName.isEmpty()){
+ String urlItunesImageString = ENTMainUtilsLocalServiceUtil.getPublicFrontBlogUrl(companyId) + "get_item_file/itemId/" + item.getItemId() + "/image/" + HttpUtil.encodeURL(imageItemFileName);
+ Element itunesImage = doc.createElement("itunes:image");
+ itunesImage.setAttribute("href", urlItunesImageString);
+ itemEl.appendChild(itunesImage);
+ }
+
+ // guid item
+ Element guidItem = doc.createElement("guid");
+ guidItem.appendChild(doc.createTextNode(linkItemString));
+ itemEl.appendChild(guidItem);
+
+ nbItems--;
+ }
+ } else {
+ break;
+ }
+ }
+
+ // Ecrit le contenu dans un fichier xml
+ TransformerFactory transformerFactory = TransformerFactory.newInstance();
+ Transformer transformer = transformerFactory.newTransformer();
+ DOMSource source = new DOMSource(doc);
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ Result outputTarget = new StreamResult(outputStream);
+ transformer.transform(source, outputTarget);
+ byte[] byteArray = outputStream.toByteArray();
+ is = new ByteArrayInputStream(byteArray);
+
+ int contentLength = byteArray.length;
+ ServletResponseServiceUtil.sendFile(response, channelId + ".xml", is, contentLength, "application/rss+xml", "inline");
+
+ } catch (final ParserConfigurationException pce) {
+ pce.printStackTrace();
+ } catch (final TransformerException tfe) {
+ tfe.printStackTrace();
+ } finally {
+ if(is != null){
+ is.close();
+ }
+ }
+ }
+
+}