Example usage for org.apache.commons.lang3 StringEscapeUtils unescapeHtml4

List of usage examples for org.apache.commons.lang3 StringEscapeUtils unescapeHtml4

Introduction

In this page you can find the example usage for org.apache.commons.lang3 StringEscapeUtils unescapeHtml4.

Prototype

public static final String unescapeHtml4(final String input) 

Source Link

Document

Unescapes a string containing entity escapes to a string containing the actual Unicode characters corresponding to the escapes.

Usage

From source file:org.openestate.is24.restapi.utils.XmlUtils.java

/**
 * Write a {@link String} value into XML output.
 *
 * @param value//  w  ww  .j  ava 2s  .  c o m
 * XML string
 *
 * @param minLength
 * minimal length
 *
 * @param maxLength
 * maximal length
 *
 * @return
 * XML string
 *
 * @throws IllegalArgumentException
 * if a validation error occured
 */
private static String printText(String value, Integer minLength, Integer maxLength) {
    String val = StringUtils.trimToNull(value);
    if (val == null) {
        throw new IllegalArgumentException("The provided text '" + value + "' is invalid!");
    }
    if (minLength != null && val.length() < minLength) {
        throw new IllegalArgumentException(
                "The provided text " + value + " is too short (minimum is " + minLength + ")!");
    }
    val = StringEscapeUtils.unescapeHtml4(value);

    // replace <br> with line breaks
    Matcher m = BR_TAG_PATTERN.matcher(val);
    val = StringUtils.trimToEmpty(m.replaceAll(SystemUtils.LINE_SEPARATOR));

    // strip any other html code
    m = ANY_TAG_PATTERN.matcher(val);
    val = StringUtils.trimToEmpty(m.replaceAll(""));
    val = StringUtils.replace(val, "<", "");
    val = StringUtils.replace(val, ">", "");

    return (maxLength != null) ? StringUtils.abbreviate(val, maxLength) : val;
}

From source file:org.opens.tanaguru.processing.ProcessRemarkServiceImplTest.java

/**
 * Test of setDocument method, of class ProcessRemarkServiceImpl.
 *///from w  w  w .  ja  va  2 s .c  o  m
public void testGetSnippetFromElement() {
    ProcessRemarkServiceImpl instance = new ProcessRemarkServiceImpl(null, null, null, null);

    //--------------------------------------------------------------------//
    //-----------------------Test1----------------------------------------//
    //--------------------------------------------------------------------//
    String rawHtml = "<label> <span>Rechercher:</span> "
            + "<input type=\"text\" onkeyup=\"return CatchEnter(event);\" "
            + "class=\"text\" id=\"searchfield\" " + "name=\"search&qudsqqqssqdsqdsqdo\" /></label>";
    Document document = Jsoup.parse(rawHtml);
    Element element = document.getElementsByTag("label").iterator().next();
    String snippet = StringEscapeUtils.unescapeHtml4(instance.getSnippetFromElement(element));
    String expectedSnippet = "<label> <span>Rechercher:</span> "
            + "<input type=\"text\" onkeyup=\"return CatchEnter(event);\" "
            + "class=\"text\" id=\"searchfield\" " + "name=\"search&amp;qudsqqqssqdsqdsqdo\" />[...]</label>";
    assertEquals(expectedSnippet, snippet);

    //--------------------------------------------------------------------//
    //-----------------------Test2----------------------------------------//
    //--------------------------------------------------------------------//
    rawHtml = "<label> <span>New Rechercher:</span> "
            + "<p title=\"some title here\" onkeyup=\"return CatchEnter(event);\" "
            + " id=\"searchfield\" class=\"myclass other-class1 other-class2\" > " + "anything</p></label>";
    document = Jsoup.parse(rawHtml);
    element = document.getElementsByTag("label").iterator().next();
    snippet = StringEscapeUtils.unescapeHtml4(instance.getSnippetFromElement(element));
    expectedSnippet = "<label> <span>New Rechercher:</span> "
            + "<p title=\"some title here\" onkeyup=\"return CatchEnter(event);\""
            + " id=\"searchfield\" class=\"myclass other-class1 other-class2\">" + "[...]</p>[...]</label>";
    assertEquals(expectedSnippet, snippet);

    //--------------------------------------------------------------------//
    //-----------------------Test3----------------------------------------//
    //--------------------------------------------------------------------//
    rawHtml = "<iframe align=\"left\" width=\"315px\" " + "scrolling=\"no\" height=\"160px\" frameborder=\"0\" "
            + "id=\"link-meteo\" src=\"http://www.anyUrl.com/module/onelocationsearch?ShowSearch=true&amp;StartDate=2012-06-01&amp;Days=2&amp;location=bruxelles&amp;url=http://meteo1.lavenir.net&amp;cssfile=http://lavenir.net/extra/weather/styles.css\">"
            + "</iframe> ";
    document = Jsoup.parse(rawHtml);
    element = document.getElementsByTag("iframe").iterator().next();
    snippet = StringEscapeUtils.unescapeHtml4(instance.getSnippetFromElement(element));
    expectedSnippet = rawHtml.trim();
    assertEquals(expectedSnippet, snippet);

    //--------------------------------------------------------------------//
    //-----------------------Test4----------------------------------------//
    //--------------------------------------------------------------------//
    rawHtml = " <center>  <script type=\"text/javascript\">    if (articledetail == false) initAdhese('IMU.SUPER.WIDE');     </script> "
            + "<script src=\"http://anyUrl.com/ad3/sl_ave_home_-IMU.SUPER.WIDE/lafr/rn92/pv1/brFirefox;Firefox17;Linux;screenundefined/in;prx;;gmbl;/?t=1381234838205\" type=\"text/javascript\"></script> "
            + " <div class=\"adhese_300x250\">  <script src=\"http://1.adhesecdn.be/pool/lib/68641.js?t=1371729603000\"></script> "
            + "<script src=\"http://anyUrl.com/pagead/show_ads.js\" type=\"text/javascript\"></script>"
            + "<ins style=\"display:inline-table;border:none;height:250px;margin:0;padding:0;position:relative;visibility:visible;width:300px\">"
            + "<ins style=\"display:block;border:none;height:250px;margin:0;padding:0;position:relative;visibility:visible;width:300px\" id=\"aswift_1_anchor\">"
            + "<iframe width=\"300\" scrolling=\"no\" height=\"250\" frameborder=\"0\" style=\"left:0;position:absolute;top:0;\" name=\"aswift_1\" id=\"aswift_1\" onload=\"var i=this.id,s=window.google_iframe_oncopy,H=s&amp;&amp;s.handlers,h=H&amp;&amp;H[i],w=this.contentWindow,d;try{d=w.document}catch(e){}if(h&amp;&amp;d&amp;&amp;(!d.body||!d.body.firstChild)){if(h.call){setTimeout(h,0)}else if(h.match){w.location.replace(h)}}\" allowtransparency=\"true\" hspace=\"0\" vspace=\"0\" marginheight=\"0\" marginwidth=\"0\"></iframe>"
            + "</ins>" + "</ins>" + "</div> " + "</center> ";
    document = Jsoup.parse(rawHtml);
    element = document.getElementsByTag("center").iterator().next();
    snippet = StringEscapeUtils.unescapeHtml4(instance.getSnippetFromElement(element));
    expectedSnippet = "<center> <script type=\"text/javascript\"> if (articledetail == false) initAdhese('IMU.SUPER.WIDE'); </script> "
            + "<script src=\"http://anyUrl.com/ad3/sl_ave_home_-IMU.SUPER.WIDE/lafr/rn92/pv1/brFirefox;Firefox17;Linux;screenundefined/in;prx;;gmbl;/?t=1381234838205\" type=\"text/javascript\">[...]</script>"
            + "[...]</center>";
    assertEquals(expectedSnippet, snippet);
}

From source file:org.opensextant.xtext.collectors.sharepoint.SPLink.java

/**
 * TODO: fix site vs. base link/*w  w  w.ja va 2 s .c  o  m*/
 * 
 * @param link
 *            a URL
 * @param base
 *            where the URL was found
 * @throws MalformedURLException
 *             err that happens if URLs are poorly formatted.
 * @throws UnsupportedEncodingException
 *             err that happens occasionally
 * @throws NoSuchAlgorithmException
 *             err that never happens
 */
public SPLink(String link, URL base)
        throws MalformedURLException, UnsupportedEncodingException, NoSuchAlgorithmException {
    super(link, base, base);

    if (isSharepointFolder()) {
        urlValue = StringEscapeUtils.unescapeHtml4(URLDecoder.decode(urlValue, "UTF-8"));
    }

    if (isAbsolute()) {
        absoluteURL = new URL(urlValue);
    } else {
        if (base == null) {
            throw new MalformedURLException("Unknown parent URL for arg baseUrl");
        }
        referrerURL = base; // aka Parent or containing page, folder or
        // other node
        absoluteURL = new URL(referrerURL, urlValue);
    }

    if (isSharepointFolder()) {
        parseURL();
        simplifiedURL = new URL(referrerURL, params.getProperty("RootFolder"));

        String[] pathParts = simplifiedURL.getPath().split("/");
        StringBuilder buf = new StringBuilder();
        for (String p : pathParts) {
            if (p.length() > 0) {
                buf.append('/');
                buf.append(encodePathSegment(p));
            }
        }
        simplifiedURL = new URL(simplifiedURL, buf.toString());
    }
}

From source file:org.orbisgis.coremap.layerModel.mapcatalog.RemoteMapCatalog.java

/**
 * Read the parser and feed the provided list with workspaces
 * @param workspaces Writable, empty list of workspaces
 * @param parser Opened parser//from www . j a v  a  2 s.  co m
 * @throws XMLStreamException 
 */
public void parseXML(List<Workspace> workspaces, XMLStreamReader parser) throws XMLStreamException {
    List<String> hierarchy = new ArrayList<String>();
    // Hold workspace name
    StringBuilder characters = new StringBuilder();
    // Starting with a valid event, iterating while the parser
    // does not reach the end document XML tag
    for (int event = parser.next(); event != XMLStreamConstants.END_DOCUMENT; event = parser.next()) {
        // For each XML elements
        switch (event) {
        case XMLStreamConstants.START_ELEMENT:
            hierarchy.add(parser.getLocalName());
            break;
        case XMLStreamConstants.END_ELEMENT:
            if (RemoteCommons.endsWith(hierarchy, "workspaces", "workspace", "name")) {
                workspaces.add(new Workspace(cParams, characters.toString().trim()));
            }
            hierarchy.remove(hierarchy.size() - 1);
            characters = new StringBuilder(); // Clear the string buffer
            break;
        case XMLStreamConstants.CHARACTERS:
            characters.append(StringEscapeUtils.unescapeHtml4(parser.getText()));
            break;
        }
    }
}

From source file:org.orbisgis.coremap.layerModel.mapcatalog.Workspace.java

/**
 * Read the parser and feed the provided list with workspaces
 * @param mapContextList Writable, empty list of RemoteMapContext
 * @param parser Opened parser//from ww  w  .  j  a va 2s  .  c om
 * @throws XMLStreamException 
 */
public void parseXML(List<RemoteMapContext> mapContextList, XMLStreamReader parser)
        throws XMLStreamException, UnsupportedEncodingException {
    List<String> hierarchy = new ArrayList<String>();
    RemoteMapContext curMapContext = null;
    Locale curLocale = null;
    StringBuilder characters = new StringBuilder();
    for (int event = parser.next(); event != XMLStreamConstants.END_DOCUMENT; event = parser.next()) {
        // For each XML elements
        switch (event) {
        case XMLStreamConstants.START_ELEMENT:
            hierarchy.add(parser.getLocalName());
            if (RemoteCommons.endsWith(hierarchy, "contexts", "context")) {
                curMapContext = new RemoteOwsMapContext(cParams);
                curMapContext.setWorkspaceName(workspaceName);
            }
            // Parse attributes
            for (int attributeId = 0; attributeId < parser.getAttributeCount(); attributeId++) {
                String attributeName = parser.getAttributeLocalName(attributeId);
                if (attributeName.equals("id")) {
                    curMapContext.setId(Integer.parseInt(parser.getAttributeValue(attributeId)));
                } else if (attributeName.equals("date")) {
                    String attributeValue = parser.getAttributeValue(attributeId);
                    try {
                        curMapContext.setDate(parseDate(attributeValue));
                    } catch (ParseException ex) {
                        LOGGER.warn(I18N.tr("Cannot parse the provided date {0}", attributeValue), ex);
                    }
                } else if (attributeName.equals("lang")) {
                    curLocale = LocalizedText.forLanguageTag(parser.getAttributeValue(attributeId));
                }
            }
            break;
        case XMLStreamConstants.END_ELEMENT:
            if (RemoteCommons.endsWith(hierarchy, "contexts", "context")) {
                mapContextList.add(curMapContext);
                curMapContext = null;
            } else if (RemoteCommons.endsWith(hierarchy, "contexts", "context", "title")) {
                Locale descLocale = Locale.getDefault();
                if (curLocale != null) {
                    descLocale = curLocale;
                }
                curMapContext.getDescription().addTitle(descLocale,
                        StringEscapeUtils.unescapeHtml4(characters.toString().trim()));
            } else if (RemoteCommons.endsWith(hierarchy, "contexts", "context", "abstract")) {
                Locale descLocale = Locale.getDefault();
                if (curLocale != null) {
                    descLocale = curLocale;
                }
                curMapContext.getDescription().addAbstract(descLocale,
                        StringEscapeUtils.unescapeHtml4(characters.toString().trim()));
            }
            characters = new StringBuilder();
            curLocale = null;
            hierarchy.remove(hierarchy.size() - 1);
            break;
        case XMLStreamConstants.CHARACTERS:
            characters.append(StringEscapeUtils.unescapeHtml4(parser.getText()));
            break;
        }
    }
}

From source file:org.pocketcampus.plugin.moodle.server.old.MoodleServiceImpl.java

public CoursesListReply getCoursesList(MoodleRequest iRequest) throws TException {
    //iRequest.setICourseId(523);//tcpip
    //iRequest.setICourseId(225);//Course Demonstrator
    //iRequest.setICourseId(12101);//MI-023
    //iRequest.setICourseId(12271);//CF10100009
    //System.out.println(getCourseSections(iRequest));
    //System.out.println(getEventsList(iRequest));

    System.out.println("getCoursesList");
    String page = null;//  w  ww .  j ava2s. c o m
    //      Gson gson = new Gson();
    //NodeJson courses = null;
    Cookie cookie = new Cookie();
    cookie.importFromString(iRequest.getISessionId().getMoodleCookie());

    try {
        page = getPageWithCookie("http://moodle.epfl.ch/?redirect=0", cookie);
        //page2 = getPageWithCookie("http://moodle.epfl.ch/lib/ajax/getnavbranch.php?id=mycourses&type=0", cookie);
    } catch (IOException e) {
        e.printStackTrace();
        return new CoursesListReply(404);
    }
    if (page == null || page.indexOf("login/logout.php") == -1) {
        System.out.println("not logged in");
        return new CoursesListReply(407);
    }

    List<ItemJson> courses = fetchNode(cookie, "mycourses", 0, 20);
    if (courses == null) {
        return new CoursesListReply(404);
    }

    LinkedList<MoodleCourse> tCourses = new LinkedList<MoodleCourse>();
    for (ItemJson mcj : courses) {
        MoodleCourse mc = new MoodleCourse();
        mc.setITitle(StringEscapeUtils.unescapeHtml4(mcj.title));
        mc.setIId(Integer.parseInt(mcj.key));
        tCourses.add(mc);
    }

    CoursesListReply cl = new CoursesListReply(200);
    cl.setICourses(tCourses);
    return cl;
}

From source file:org.pocketcampus.plugin.moodle.server.old.MoodleServiceImpl.java

private String stripHtmlTags(String html) {
    // or keep it client-side
    // android.text.Html.fromHtml(instruction).toString()

    // should first remove invisible elements
    html = html.replaceAll("class=\"left side[^<]+<", "");
    html = html.replaceAll("class=\"weekdates[^<]+<", "");
    html = html.replaceAll("class=\"accesshide[^<]+<", "");

    html = html.replaceAll("<br />", "\n");
    html = html.replaceAll("<h2>", "\n");
    html = html.replaceAll("</h2>", "\n");
    html = html.replaceAll("<[^>]+>", "");

    html = StringEscapeUtils.unescapeHtml4(html);
    html = html.replaceAll("[\\xA0]+", " "); // replace non-breaking spaces (code 160) with normal spaces (code 32)
    html = html.replaceAll("[\\t\\r\\v\\f]+", ""); // remove some weird characters
    html = html.replaceAll("[\\n][ ]+", "\n"); // remove spaces at the beginning of a line
    html = html.replaceAll("[ ]+[\\n]", "\n"); // remove spaces at the end of a line
    html = html.replaceAll("[ ]+", " "); // remove consecutive spaces
    html = html.replaceAll("[\\n]+", "\n"); // remove consecutive new-lines
    html = html.replaceAll("^[\\n]+", ""); // remove new-line characters at the beginning
    html = html.replaceAll("[\\n]+$", ""); // remove new-line characters at the end
    return html.trim();
}

From source file:org.polymap.rhei.fulltext.servlet.SearchServlet.java

@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
    log.info("Request: " + request.getQueryString());

    String srsParam = request.getParameter("srs");
    CoordinateReferenceSystem worldCRS = DEFAULT_WORLD_CRS;
    if (srsParam != null) {
        try {/*from w  w  w .ja  v  a2  s  . c o m*/
            worldCRS = CRS.decode(srsParam);
        } catch (Exception e) {
            worldCRS = DEFAULT_WORLD_CRS;
        }
    }
    log.debug("worldCRS: " + worldCRS);

    // completion request *****************************
    if (request.getParameter("term") != null) {
        String searchStr = request.getParameter("term");
        searchStr = StringEscapeUtils.unescapeHtml4(searchStr);

        try {
            JSONArray result = new JSONArray();

            for (String record : dispatcher.propose(searchStr, 7, null)) {
                //result.put( StringEscapeUtils.escapeHtml( record ) );
                result.put(record);
            }

            log.info("Response: " + result.toString());
            response.setContentType("application/json; charset=UTF-8");
            response.setCharacterEncoding("UTF-8");
            response.getWriter().println(result.toString());
        } catch (Exception e) {
            log.info("Response: " + "Fehler: " + e.getMessage(), e);
            response.setContentType("text/html");
            response.getWriter().println("Fehler: " + e.getMessage());
        }
    }

    // content request (GeoRSS/KML/GeoJSON) ***********
    else if (request.getParameter("search") != null) {
        String searchStr = request.getParameter("search");
        searchStr = URLDecoder.decode(searchStr, "UTF-8");
        log.info("    searchStr= " + searchStr);
        String outputType = request.getParameter("outputType");

        int maxResults = request.getParameter("maxResults") != null
                ? Integer.parseInt(request.getParameter("maxResults"))
                : DEFAULT_MAX_SEARCH_RESULTS;

        try {
            // gzipped response?
            CountingOutputStream cout = new CountingOutputStream(response.getOutputStream());
            OutputStream bout = cout;
            String acceptEncoding = request.getHeader("Accept-Encoding");
            if (acceptEncoding != null && acceptEncoding.toLowerCase().contains("gzip")) {
                try {
                    bout = new GZIPOutputStream(bout);
                    response.setHeader("Content-Encoding", "gzip");
                } catch (NoSuchMethodError e) {
                    // for whatever reason the syncFlush ctor is not always available
                    log.warn(e.toString());
                }
            }

            ObjectOutput out = null;
            // KML
            if ("KML".equalsIgnoreCase(outputType)) {
                throw new RuntimeException("Not supported currently.");
                //                    out = new KMLEncoder( bout );
                //                    response.setContentType( "application/vnd.google-earth.kml+xml; charset=UTF-8" );
                //                    response.setCharacterEncoding( "UTF-8" );
            }
            // JSON
            else if ("JSON".equalsIgnoreCase(outputType)) {
                response.setContentType("application/json; charset=UTF-8");
                response.setCharacterEncoding("UTF-8");
                out = new GeoJsonEncoder(bout, worldCRS);
            }
            // RSS
            else {
                // XXX figure the real client URL (without reverse proxies)
                //String baseURL = StringUtils.substringBeforeLast( request.getRequestURL().toString(), "/" ) + "/index.html";
                String baseURL = (String) System.getProperties().get("org.polymap.atlas.feed.url");
                log.info("    baseURL: " + baseURL);
                String title = (String) System.getProperties().get("org.polymap.atlas.feed.title");
                String description = (String) System.getProperties().get("org.polymap.atlas.feed.description");

                out = new GeoRssEncoder(bout, worldCRS, baseURL, title, description);
                response.setContentType("application/rss+xml; charset=UTF-8");
                response.setCharacterEncoding("UTF-8");
            }

            // make sure that empty searchStr *always* results in empty reponse 
            if (searchStr != null && searchStr.length() > 0) {
                for (JSONObject feature : dispatcher.search(searchStr, maxResults)) {
                    try {
                        out.writeObject(feature);
                    } catch (Exception e) {
                        log.warn("Error during encode: " + e, e);
                    }
                }
            }

            // make sure that streams and deflaters are flushed
            out.close();
            log.info("    written: " + cout.getCount() + " bytes");
        } catch (Exception e) {
            log.error(e.getLocalizedMessage(), e);
        }
    }
    response.flushBuffer();
}

From source file:org.primefaces.extensions.component.masterdetail.MasterDetailRenderer.java

protected void updateBreadcrumb(final FacesContext fc, final BreadCrumb breadcrumb,
        final MasterDetail masterDetail, final MasterDetailLevel mdlToRender) throws IOException {
    boolean lastMdlFound = false;
    final int levelToRender = mdlToRender.getLevel();
    final boolean isShowAllBreadcrumbItems = masterDetail.isShowAllBreadcrumbItems();

    for (final UIComponent child : masterDetail.getChildren()) {
        if (child instanceof MasterDetailLevel) {
            final MasterDetailLevel mdl = (MasterDetailLevel) child;
            final DefaultMenuItem menuItem = getMenuItemByLevel(breadcrumb, masterDetail, mdl);
            if (menuItem == null) {
                // note: don't throw exception because menuItem can be null when MasterDetail is within DataTable
                // throw new FacesException("MenuItem to master detail level " + mdl.getLevel() + " was not found");
                return;
            }//from  w  w  w. j a  v  a2s. co  m

            if (!child.isRendered()) {
                menuItem.setRendered(false);
                if (!lastMdlFound) {
                    lastMdlFound = mdl.getLevel() == mdlToRender.getLevel();
                }

                continue;
            }

            if (lastMdlFound && !isShowAllBreadcrumbItems) {
                menuItem.setRendered(false);
            } else {
                menuItem.setRendered(true);

                final Object contextValue = masterDetail.getContextValueFromFlow(fc, mdl,
                        mdl.getLevel() == mdlToRender.getLevel());
                final String contextVar = mdl.getContextVar();
                final boolean putContext = StringUtils.isNotBlank(contextVar) && contextValue != null;

                if (putContext) {
                    final Map<String, Object> requestMap = fc.getExternalContext().getRequestMap();
                    requestMap.put(contextVar, contextValue);
                }

                final UIComponent facet = mdl.getFacet(FACET_LABEL);
                if (facet != null) {
                    // swap writers
                    final ResponseWriter writer = fc.getResponseWriter();
                    final FastStringWriter fsw = new FastStringWriter();
                    final ResponseWriter clonedWriter = writer.cloneWithWriter(fsw);
                    fc.setResponseWriter(clonedWriter);

                    // render facet's children
                    facet.encodeAll(fc);

                    // restore the original writer
                    fc.setResponseWriter(writer);

                    // set menuitem label from facet
                    menuItem.setValue(StringEscapeUtils.unescapeHtml4(fsw.toString()));
                } else {
                    // set menuitem label from tag attribute
                    menuItem.setValue(mdl.getLevelLabel());
                }

                if (isShowAllBreadcrumbItems && lastMdlFound) {
                    menuItem.setDisabled(true);
                } else {
                    menuItem.setDisabled(mdl.isLevelDisabled());
                }

                if (putContext) {
                    fc.getExternalContext().getRequestMap().remove(contextVar);
                }

                if (!menuItem.isDisabled()) {
                    // set current level parameter
                    updateUIParameter(menuItem, masterDetail.getClientId(fc) + MasterDetail.CURRENT_LEVEL,
                            levelToRender);
                }
            }

            if (!lastMdlFound) {
                lastMdlFound = mdl.getLevel() == mdlToRender.getLevel();
            }
        }
    }
}

From source file:org.quantumbadger.redreader.reddit.prepared.RedditPreparedComment.java

public RedditPreparedComment(final Context context, final RedditComment comment, final long timestamp,
        final boolean needsUpdating, final RedditPreparedPost parentPost, final RedditAccount user,
        final EnumSet<PrefsUtility.AppearanceCommentHeaderItems> headerItems) {

    this.src = comment;
    this.parentPost = parentPost;
    this.headerItems = headerItems;

    // TODO custom time

    // TODO don't fetch these every time
    final TypedArray appearance = context.obtainStyledAttributes(new int[] { R.attr.rrCommentHeaderBoldCol,
            R.attr.rrCommentHeaderAuthorCol, R.attr.rrPostSubtitleUpvoteCol, R.attr.rrPostSubtitleDownvoteCol,
            R.attr.rrFlairBackCol, R.attr.rrFlairTextCol, R.attr.rrGoldBackCol, R.attr.rrGoldTextCol });

    rrCommentHeaderBoldCol = appearance.getColor(0, 255);
    rrCommentHeaderAuthorCol = appearance.getColor(1, 255);
    rrPostSubtitleUpvoteCol = appearance.getColor(2, 255);
    rrPostSubtitleDownvoteCol = appearance.getColor(3, 255);
    rrFlairBackCol = appearance.getColor(4, 0);
    rrFlairTextCol = appearance.getColor(5, 255);
    rrGoldBackCol = appearance.getColor(6, 0);
    rrGoldTextCol = appearance.getColor(7, 255);

    appearance.recycle();//from w w w  . ja v a2s  . c  o  m

    body = MarkdownParser.parse(StringEscapeUtils.unescapeHtml4(comment.body).toCharArray());
    if (comment.author_flair_text != null) {
        flair = StringEscapeUtils.unescapeHtml4(comment.author_flair_text);
    } else {
        flair = null;
    }

    idAlone = comment.id;
    idAndType = comment.name;

    if (comment.likes == null) {
        voteDirection = 0;
    } else {
        voteDirection = Boolean.TRUE.equals(comment.likes) ? 1 : -1;
    }

    saved = Boolean.TRUE.equals(comment.saved);

    lastChange = timestamp;
    if (src.likes != null) {
        RedditChangeDataManager.getInstance(context).update(src.link_id, user, this, true);
    } else if (needsUpdating) {
        RedditChangeDataManager.getInstance(context).update(src.link_id, user, this, false);
    }

    rebuildHeader(context);
}