001    /**
002     * Copyright (c) 2000-2012 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.util;
016    
017    import com.liferay.portal.kernel.util.CharPool;
018    import com.liferay.portal.kernel.util.GetterUtil;
019    import com.liferay.portal.kernel.util.PropsKeys;
020    import com.liferay.portal.kernel.util.PropsUtil;
021    import com.liferay.portal.kernel.util.StringPool;
022    import com.liferay.portal.kernel.util.StringUtil;
023    import com.liferay.portal.kernel.util.Validator;
024    
025    import com.sun.syndication.feed.synd.SyndContent;
026    import com.sun.syndication.feed.synd.SyndEntry;
027    import com.sun.syndication.feed.synd.SyndFeed;
028    import com.sun.syndication.io.FeedException;
029    import com.sun.syndication.io.SyndFeedOutput;
030    
031    import java.util.List;
032    
033    import org.jdom.IllegalDataException;
034    
035    /**
036     * @author Brian Wing Shun Chan
037     * @author Eduardo Garcia
038     */
039    public class RSSUtil {
040    
041            public static final String ATOM = "atom";
042    
043            public static final String DISPLAY_STYLE_ABSTRACT = "abstract";
044    
045            public static final String DISPLAY_STYLE_FULL_CONTENT = "full-content";
046    
047            public static final String DISPLAY_STYLE_TITLE = "title";
048    
049            public static final String ENTRY_TYPE_DEFAULT = "html";
050    
051            public static final String FEED_TYPE_DEFAULT = _getFeedTypeDefault();
052    
053            public static final String[] FEED_TYPES = _getFeedTypes();
054    
055            public static final String FORMAT_DEFAULT = getFeedTypeFormat(
056                    FEED_TYPE_DEFAULT);
057    
058            public static final String RSS = "rss";
059    
060            /**
061             * @deprecated Renamed to {@link #FORMAT_DEFAULT}
062             */
063            public static final String TYPE_DEFAULT = FORMAT_DEFAULT;
064    
065            public static final double VERSION_DEFAULT = getFeedTypeVersion(
066                    FEED_TYPE_DEFAULT);
067    
068            public static String export(SyndFeed feed) throws FeedException {
069                    RSSThreadLocal.setExportRSS(true);
070    
071                    feed.setEncoding(StringPool.UTF8);
072    
073                    SyndFeedOutput output = new SyndFeedOutput();
074    
075                    try {
076                            return output.outputString(feed);
077                    }
078                    catch (IllegalDataException ide) {
079    
080                            // LEP-4450
081    
082                            _regexpStrip(feed);
083    
084                            return output.outputString(feed);
085                    }
086            }
087    
088            public static String getFeedType(String type, double version) {
089                    return type + StringPool.UNDERLINE + version;
090            }
091    
092            public static String getFeedTypeFormat(String feedType) {
093                    if (Validator.isNotNull(feedType)) {
094                            String[] parts = StringUtil.split(feedType, StringPool.UNDERLINE);
095    
096                            if (parts.length == 2) {
097                                    return GetterUtil.getString(parts[0], FORMAT_DEFAULT);
098                            }
099                    }
100    
101                    return FORMAT_DEFAULT;
102            }
103    
104            public static String getFeedTypeName(String feedType) {
105                    String type = getFeedTypeFormat(feedType);
106    
107                    if (type.equals(ATOM)) {
108                            type = "Atom";
109                    }
110                    else if (type.equals(RSS)) {
111                            type = "RSS";
112                    }
113    
114                    double version = getFeedTypeVersion(feedType);
115    
116                    return type + StringPool.SPACE + version;
117            }
118    
119            public static double getFeedTypeVersion(String feedType) {
120                    if (Validator.isNotNull(feedType)) {
121                            String[] parts = StringUtil.split(feedType, StringPool.UNDERLINE);
122    
123                            if (parts.length == 2) {
124                                    return GetterUtil.getDouble(parts[1], VERSION_DEFAULT);
125                            }
126                    }
127    
128                    return VERSION_DEFAULT;
129            }
130    
131            public static String getFormatType(String format) {
132                    if (format == null) {
133                            return FORMAT_DEFAULT;
134                    }
135    
136                    int x = format.indexOf(ATOM);
137    
138                    if (x >= 0) {
139                            return ATOM;
140                    }
141    
142                    int y = format.indexOf(RSS);
143    
144                    if (y >= 0) {
145                            return RSS;
146                    }
147    
148                    return FORMAT_DEFAULT;
149            }
150    
151            public static double getFormatVersion(String format) {
152                    if (format == null) {
153                            return VERSION_DEFAULT;
154                    }
155    
156                    int x = format.indexOf("10");
157    
158                    if (x >= 0) {
159                            return 1.0;
160                    }
161    
162                    int y = format.indexOf("20");
163    
164                    if (y >= 0) {
165                            return 2.0;
166                    }
167    
168                    return VERSION_DEFAULT;
169            }
170    
171            private static String _getFeedTypeDefault() {
172                    return GetterUtil.getString(
173                            PropsUtil.get(PropsKeys.RSS_FEED_TYPE_DEFAULT),
174                            getFeedType(ATOM, 1.0));
175            }
176    
177            private static String[] _getFeedTypes() {
178                    return GetterUtil.getStringValues(
179                            PropsUtil.getArray(PropsKeys.RSS_FEED_TYPES),
180                            new String[] {FEED_TYPE_DEFAULT});
181            }
182    
183            private static String _regexpStrip(String text) {
184                    text = Normalizer.normalizeToAscii(text);
185    
186                    char[] array = text.toCharArray();
187    
188                    for (int i = 0; i < array.length; i++) {
189                            String s = String.valueOf(array[i]);
190    
191                            if (!s.matches(_REGEXP_STRIP)) {
192                                    array[i] = CharPool.SPACE;
193                            }
194                    }
195    
196                    return new String(array);
197            }
198    
199            private static void _regexpStrip(SyndFeed syndFeed) {
200                    syndFeed.setTitle(_regexpStrip(syndFeed.getTitle()));
201                    syndFeed.setDescription(_regexpStrip(syndFeed.getDescription()));
202    
203                    List<SyndEntry> syndEntries = syndFeed.getEntries();
204    
205                    for (SyndEntry syndEntry : syndEntries) {
206                            syndEntry.setTitle(_regexpStrip(syndEntry.getTitle()));
207    
208                            SyndContent syndContent = syndEntry.getDescription();
209    
210                            syndContent.setValue(_regexpStrip(syndContent.getValue()));
211                    }
212            }
213    
214            private static final String _REGEXP_STRIP = "[\\d\\w]";
215    
216    }