Package org.apache.click.element

Source Code of org.apache.click.element.CssStyle

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.click.element;

import java.util.HashMap;
import java.util.Map;
import org.apache.click.Context;
import org.apache.click.util.HtmlStringBuffer;
import org.apache.commons.lang.builder.HashCodeBuilder;

/**
* Provides a Css HEAD element for including <tt>inline</tt> Cascading
* Stylesheets using the &lt;style&gt; tag.
* <p/>
* Example usage:
*
* <pre class="prettyprint">
* public class MyPage extends Page {
*
*     public List getHeadElements() {
*         // We use lazy loading to ensure the CSS import is only added the
*         // first time this method is called.
*         if (headElements == null) {
*             // Get the header entries from the super implementation
*             headElements = super.getHeadElements();
*
*             CssStyle cssStyle = new CssStyle("body { font: 12px arial; }");
*             headElements.add(cssStyle);
*         }
*         return headElements;
*     }
* } </pre>
*
* The <tt>cssStyle</tt> instance will render as follows:
*
* <pre class="prettyprint">
* &lt;style type="text/css"&gt;
* body { font: 12px arial; }
* &lt;/style&gt; </pre>
*
* Below is an example showing how to render inline CSS from a Velocity
* template.
* <p/>
* First we create a Velocity template <tt>(/css/style-template.css)</tt> which
* contains the variable <tt>$context</tt> that must be replaced at runtime with
* the application <tt>context path</tt>:
*
* <pre class="prettyprint">
* .blue {
*     background: #00ff00 url('$context/css/blue.png') no-repeat fixed center;
* } </pre>
*
* Next is the Page implementation:
*
* <pre class="prettyprint">
* public class MyPage extends Page {
*
*     public List getHeadElements() {
*         // We use lazy loading to ensure the CSS is only added the first time
*         // this method is called.
*         if (headElements == null) {
*             // Get the head elements from the super implementation
*             headElements = super.getHeadElements();
*
*             Context context = getContext();
*
*             // Create a default template model to pass to the template
*             Map model = ClickUtils.createTemplateModel(this, context);
*
*             // Specify the path to CSS template
*             String templatePath = "/css/style-template.css";
*
*             // Create the inline Css for the given template path and model
*             CssStyle cssStyle = new CssStyle(templatePath, model);
*             headElements.add(cssStyle);
*         }
*         return headElements;
*     }
* } </pre>
*
* The <tt>Css</tt> above will render as follows (assuming the context path is
* <tt>myApp</tt>):
*
* <pre class="prettyprint">
* &lt;style type="text/css"&gt;
* .blue {
*     background: #00ff00 url('/myApp/css/blue.png') no-repeat fixed center;
* }
* &lt;/style&gt; </pre>
*
* <h3>Character data (CDATA) support</h3>
*
* Sometimes it is necessary to wrap <tt>inline</tt> {@link CssStyle Css} in
* CDATA tags. Two use cases are common for doing this:
* <ul>
* <li>For XML parsing: When using Ajax one often send back partial
* XML snippets to the browser, which is parsed as valid XML. However the XML
* parser will throw an error if the content contains reserved XML characters
* such as '&amp;', '&lt;' and '&gt;'. For these situations it is recommended
* to wrap the style content inside CDATA tags.
* </li>
* <li>XHTML validation: if you want to validate your site using an XHTML
* validator e.g: <a target="_blank" href="http://validator.w3.org/">http://validator.w3.org/</a>.</li>
* </ul>
*
* To wrap the CSS Style content in CDATA tags, set
* {@link #setCharacterData(boolean)} to true. Below is shown how the Css
* content would be rendered:
*
* <pre class="codeHtml">
* &lt;style type="text/css"&gt;
<span style="color:#3F7F5F">/&lowast;&lt;![CDATA[&lowast;/</span>
*
*  div &gt; p {
*    border: 1px solid black;
*  }
*
<span style="color:#3F7F5F">/&lowast;]]&gt;&lowast;/</span>
* &lt;/style&gt; </pre>
*
* Notice the CDATA tags are commented out which ensures older browsers that
* don't understand the CDATA tag, will ignore it and only process the actual
* content.
* <p/>
* For an overview of XHTML validation and CDATA tags please see
* <a target="_blank" href="http://javascript.about.com/library/blxhtml.htm">http://javascript.about.com/library/blxhtml.htm</a>.
*/
public class CssStyle extends ResourceElement {

    private static final long serialVersionUID = 1L;

     // -------------------------------------------------------------- Variables

    /** The inline Css content. */
    private String content;

    /**
     * Indicates if the HeadElement's content should be wrapped in a CDATA tag.
     */
    private boolean characterData = false;

    /** The path of the template to render. */
    private String template;

    /** The model of the template to render. */
    private Map model;

    // ------------------------------------------------------------ Constructor

    /**
     * Construct a new Css style element.
     */
    public CssStyle() {
        this(null);
    }

    /**
     * Construct a new Css style element with the given content.
     *
     * @param content the Css content
     */
    public CssStyle(String content) {
        if (content != null) {
            this.content = content;
        }
        setAttribute("type", "text/css");
    }

    /**
     * Construct a new Css style element for the given template path
     * and template model.
     * <p/>
     * When the CssStyle is rendered the template and model will be merged and
     * the result will be rendered together with any CssStyle
     * {@link #setContent(java.lang.String) content}.
     * <p/>
     *
     * For example:
     * <pre class="prettyprint">
     * public class MyPage extends Page {
     *     public void onInit() {
     *         Context context = getContext();
     *
     *         // Create a default template model
     *         Map model = ClickUtils.createTemplateModel(this, context);
     *
     *         // Create CssStyle for the given template path and model
     *         CssStyle style = new CssStyle("/mypage-template.css", model);
     *
     *         // Add style to the Page Head elements
     *         getHeadElements().add(style);
     *     }
     * } </pre>
     *
     * @param template the path of the template to render
     * @param model the template model
     */
    public CssStyle(String template, Map model) {
        this(null);
        setTemplate(template);
        setModel(model);
    }

    // ------------------------------------------------------ Public properties

    /**
     * Returns the Css HTML tag: &lt;style&gt;.
     *
     * @return the Css HTML tag: &lt;style&gt;
     */
    public String getTag() {
        return "style";
    }

    /**
     * Return the CssStyle content.
     *
     * @return the CssStyle content
     */
    public String getContent() {
        return content;
    }

    /**
     * Set the CssStyle content.
     *
     * @param content the CssStyle content
     */
    public void setContent(String content) {
        this.content = content;
    }

    /**
     * Return true if the CssStyle's content should be wrapped in CDATA tags,
     * false otherwise.
     *
     * @return true if the CssStyle's content should be wrapped in CDATA tags,
     * false otherwise
     */
    public boolean isCharacterData() {
        return characterData;
    }

    /**
     * Sets whether the CssStyle's content should be wrapped in CDATA tags or
     * not.
     *
     * @param characterData true indicates that the CssStyle's content should be
     * wrapped in CDATA tags, false otherwise
     */
    public void setCharacterData(boolean characterData) {
        this.characterData = characterData;
    }

    /**
     * Return the path of the template to render.
     *
     * @see #setTemplate(java.lang.String)
     *
     * @return the path of the template to render
     */
    public String getTemplate() {
        return template;
    }

    /**
     * Set the path of the template to render.
     * <p/>
     * If the {@link #template} property is set, the template and {@link #model}
     * will be merged and the result will be rendered together with any CssStyle
     * {@link #setContent(java.lang.String) content}.
     *
     * @param template the path of the template to render
     */
    public void setTemplate(String template) {
        this.template = template;
    }

    /**
     * Return the model of the {@link #setTemplate(java.lang.String) template}
     * to render.
     *
     * @see #setModel(java.util.Map)
     *
     * @return the model of the template to render
     */
    public Map getModel() {
        return model;
    }

    /**
     * Set the model of the template to render.
     * <p/>
     * If the {@link #template} property is set, the template and {@link #model}
     * will be merged and the result will be rendered together with any CssStyle
     * {@link #setContent(java.lang.String) content}.
     *
     * @param model the model of the template to render
     */
    public void setModel(Map model) {
        this.model = model;
    }

    // --------------------------------------------------------- Public Methods

    /**
     * Render the HTML representation of the CssStyle element to the specified
     * buffer.
     *
     * @param buffer the buffer to render output to
     */
    public void render(HtmlStringBuffer buffer) {

        // Render IE conditional comment if conditional comment was set
        renderConditionalCommentPrefix(buffer);

        buffer.elementStart(getTag());

        buffer.appendAttribute("id", getId());
        appendAttributes(buffer);

        buffer.closeTag();

        buffer.append("\n");

        // Render CDATA tag if necessary
        renderCharacterDataPrefix(buffer);

        renderContent(buffer);

        renderCharacterDataSuffix(buffer);

        buffer.append("\n");

        buffer.elementEnd(getTag());

        renderConditionalCommentSuffix(buffer);
    }

    /**
     * @see java.lang.Object#equals(java.lang.Object)
     *
     * @param o the object with which to compare this instance with
     * @return true if the specified object is the same as this object
     */
    public boolean equals(Object o) {
        if (!isUnique()) {
            return super.equals(o);
        }

        //1. Use the == operator to check if the argument is a reference to this object.
        if (o == this) {
            return true;
        }

        //2. Use the instanceof operator to check if the argument is of the correct type.
        if (!(o instanceof CssStyle)) {
            return false;
        }

        //3. Cast the argument to the correct type.
        CssStyle that = (CssStyle) o;

        String id = getId();
        String thatId = that.getId();
        return id == null ? thatId == null : id.equals(thatId);
    }

    /**
     * @see java.lang.Object#hashCode()
     *
     * @return a hash code value for this object
     */
    public int hashCode() {
        if (!isUnique()) {
            return super.hashCode();
        }
        return new HashCodeBuilder(17, 37).append(getId()).toHashCode();
    }

    // ------------------------------------------------------ Protected Methods

    /**
     * Render the CssStyle {@link #setContent(java.lang.String) content}
     * to the specified buffer.
     * <p/>
     * <b>Please note:</b> if the {@link #setTemplate(java.lang.String) template}
     * property is set, this method will merge the {@link #setTemplate(java.lang.String) template}
     * and {@link #setModel(java.util.Map) model} and the result will be
     * rendered, together with the CssStyle
     * {@link #setContent(java.lang.String) content},
     * to the specified buffer.
     *
     * @param buffer the buffer to append the output to
     */
    protected void renderContent(HtmlStringBuffer buffer) {
        if (getTemplate() != null) {
            Context context = getContext();

            Map templateModel = getModel();
            if (templateModel == null) {
                templateModel = new HashMap();
            }
            buffer.append(context.renderTemplate(getTemplate(), templateModel));

        }

        if (getContent() != null) {
            buffer.append(getContent());
        }
    }

    // ------------------------------------------------ Package Private Methods

    /**
     * Render the CDATA tag prefix to the specified buffer if
     * {@link #isCharacterData()} returns true. The default value is
     * <tt>/&lowast;&lt;![CDATA[&lowast;/</tt>.
     *
     * @param buffer buffer to append the conditional comment prefix
     */
    void renderCharacterDataPrefix(HtmlStringBuffer buffer) {
        // Wrap character data in CDATA block
        if (isCharacterData()) {
            buffer.append("/*<![CDATA[*/ ");
        }
    }

    /**
     * Render the CDATA tag suffix to the specified buffer if
     * {@link #isCharacterData()} returns true. The default value is
     * <tt>/&lowast;]]&gt;&lowast;/</tt>.
     *
     * @param buffer buffer to append the conditional comment prefix
     */
    void renderCharacterDataSuffix(HtmlStringBuffer buffer) {
        if (isCharacterData()) {
            buffer.append(" /*]]>*/");
        }
    }
}
TOP

Related Classes of org.apache.click.element.CssStyle

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.