001    /**
002     * Copyright (c) 2000-present 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_DEFAULT =
046                    _getDisplayStyleDefault();
047    
048            public static final String DISPLAY_STYLE_FULL_CONTENT = "full-content";
049    
050            public static final String DISPLAY_STYLE_TITLE = "title";
051    
052            public static final String[] DISPLAY_STYLES = new String[] {
053                    DISPLAY_STYLE_ABSTRACT, DISPLAY_STYLE_FULL_CONTENT, DISPLAY_STYLE_TITLE
054            };
055    
056            public static final String ENTRY_TYPE_DEFAULT = "html";
057    
058            public static final String FEED_TYPE_DEFAULT = _getFeedTypeDefault();
059    
060            public static final String[] FEED_TYPES = _getFeedTypes();
061    
062            public static final String FORMAT_DEFAULT = getFeedTypeFormat(
063                    FEED_TYPE_DEFAULT);
064    
065            public static final String RSS = "rss";
066    
067            /**
068             * @deprecated As of 6.2.0, replaced by {@link #FORMAT_DEFAULT}
069             */
070            @Deprecated
071            public static final String TYPE_DEFAULT = FORMAT_DEFAULT;
072    
073            public static final double VERSION_DEFAULT = getFeedTypeVersion(
074                    FEED_TYPE_DEFAULT);
075    
076            public static String export(SyndFeed feed) throws FeedException {
077                    RSSThreadLocal.setExportRSS(true);
078    
079                    feed.setEncoding(StringPool.UTF8);
080    
081                    SyndFeedOutput output = new SyndFeedOutput();
082    
083                    try {
084                            return output.outputString(feed);
085                    }
086                    catch (IllegalDataException ide) {
087    
088                            // LEP-4450
089    
090                            _regexpStrip(feed);
091    
092                            return output.outputString(feed);
093                    }
094            }
095    
096            public static String getFeedType(String type, double version) {
097                    return type + StringPool.UNDERLINE + version;
098            }
099    
100            public static String getFeedTypeFormat(String feedType) {
101                    if (Validator.isNotNull(feedType)) {
102                            String[] parts = StringUtil.split(feedType, StringPool.UNDERLINE);
103    
104                            if (parts.length == 2) {
105                                    return GetterUtil.getString(parts[0], FORMAT_DEFAULT);
106                            }
107                    }
108    
109                    return FORMAT_DEFAULT;
110            }
111    
112            public static String getFeedTypeName(String feedType) {
113                    String type = getFeedTypeFormat(feedType);
114    
115                    if (type.equals(ATOM)) {
116                            type = "Atom";
117                    }
118                    else if (type.equals(RSS)) {
119                            type = "RSS";
120                    }
121    
122                    double version = getFeedTypeVersion(feedType);
123    
124                    return type + StringPool.SPACE + version;
125            }
126    
127            public static double getFeedTypeVersion(String feedType) {
128                    if (Validator.isNotNull(feedType)) {
129                            String[] parts = StringUtil.split(feedType, StringPool.UNDERLINE);
130    
131                            if (parts.length == 2) {
132                                    return GetterUtil.getDouble(parts[1], VERSION_DEFAULT);
133                            }
134                    }
135    
136                    return VERSION_DEFAULT;
137            }
138    
139            public static String getFormatType(String format) {
140                    if (format == null) {
141                            return FORMAT_DEFAULT;
142                    }
143    
144                    int x = format.indexOf(ATOM);
145    
146                    if (x >= 0) {
147                            return ATOM;
148                    }
149    
150                    int y = format.indexOf(RSS);
151    
152                    if (y >= 0) {
153                            return RSS;
154                    }
155    
156                    return FORMAT_DEFAULT;
157            }
158    
159            public static double getFormatVersion(String format) {
160                    if (format == null) {
161                            return VERSION_DEFAULT;
162                    }
163    
164                    int x = format.indexOf("10");
165    
166                    if (x >= 0) {
167                            return 1.0;
168                    }
169    
170                    int y = format.indexOf("20");
171    
172                    if (y >= 0) {
173                            return 2.0;
174                    }
175    
176                    return VERSION_DEFAULT;
177            }
178    
179            private static String _getDisplayStyleDefault() {
180                    return GetterUtil.getString(
181                            PropsUtil.get(PropsKeys.RSS_FEED_DISPLAY_STYLE_DEFAULT),
182                            DISPLAY_STYLE_FULL_CONTENT);
183            }
184    
185            private static String _getFeedTypeDefault() {
186                    return GetterUtil.getString(
187                            PropsUtil.get(PropsKeys.RSS_FEED_TYPE_DEFAULT),
188                            getFeedType(ATOM, 1.0));
189            }
190    
191            private static String[] _getFeedTypes() {
192                    return GetterUtil.getStringValues(
193                            PropsUtil.getArray(PropsKeys.RSS_FEED_TYPES),
194                            new String[] {FEED_TYPE_DEFAULT});
195            }
196    
197            private static String _regexpStrip(String text) {
198                    text = Normalizer.normalizeToAscii(text);
199    
200                    char[] array = text.toCharArray();
201    
202                    for (int i = 0; i < array.length; i++) {
203                            String s = String.valueOf(array[i]);
204    
205                            if (!s.matches(_REGEXP_STRIP)) {
206                                    array[i] = CharPool.SPACE;
207                            }
208                    }
209    
210                    return new String(array);
211            }
212    
213            private static void _regexpStrip(SyndFeed syndFeed) {
214                    syndFeed.setTitle(_regexpStrip(syndFeed.getTitle()));
215                    syndFeed.setDescription(_regexpStrip(syndFeed.getDescription()));
216    
217                    List<SyndEntry> syndEntries = syndFeed.getEntries();
218    
219                    for (SyndEntry syndEntry : syndEntries) {
220                            syndEntry.setTitle(_regexpStrip(syndEntry.getTitle()));
221    
222                            SyndContent syndContent = syndEntry.getDescription();
223    
224                            syndContent.setValue(_regexpStrip(syndContent.getValue()));
225                    }
226            }
227    
228            private static final String _REGEXP_STRIP = "[\\d\\w]";
229    
230    }