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