You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@click.apache.org by sa...@apache.org on 2009/03/12 20:20:05 UTC
svn commit: r752978 - in
/incubator/click/trunk/click/framework/src/org/apache/click/element: ./
CssImport.java CssStyle.java Element.java JsImport.java JsScript.java
ResourceElement.java
Author: sabob
Date: Thu Mar 12 19:20:04 2009
New Revision: 752978
URL: http://svn.apache.org/viewvc?rev=752978&view=rev
Log:
added element package and basic elements
Added:
incubator/click/trunk/click/framework/src/org/apache/click/element/
incubator/click/trunk/click/framework/src/org/apache/click/element/CssImport.java
incubator/click/trunk/click/framework/src/org/apache/click/element/CssStyle.java
incubator/click/trunk/click/framework/src/org/apache/click/element/Element.java
incubator/click/trunk/click/framework/src/org/apache/click/element/JsImport.java
incubator/click/trunk/click/framework/src/org/apache/click/element/JsScript.java
incubator/click/trunk/click/framework/src/org/apache/click/element/ResourceElement.java
Added: incubator/click/trunk/click/framework/src/org/apache/click/element/CssImport.java
URL: http://svn.apache.org/viewvc/incubator/click/trunk/click/framework/src/org/apache/click/element/CssImport.java?rev=752978&view=auto
==============================================================================
--- incubator/click/trunk/click/framework/src/org/apache/click/element/CssImport.java (added)
+++ incubator/click/trunk/click/framework/src/org/apache/click/element/CssImport.java Thu Mar 12 19:20:04 2009
@@ -0,0 +1,192 @@
+/*
+ * 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 org.apache.click.Context;
+import org.apache.click.util.HtmlHeader;
+import org.apache.click.util.HtmlStringBuffer;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+
+/**
+ *
+ * @author Bob Schellink
+ */
+public class CssImport extends ResourceElement {
+
+ // ----------------------------------------------------------- Constructors
+
+ /**
+ * Constructs a new CssImport link.
+ */
+ public CssImport() {
+ this(null);
+ }
+
+ /**
+ * Construct a new CssImport link with the specified <tt>href</tt> attribute.
+ * <p/>
+ * <b>Please note</b> if the given <tt>href</tt> begins with a <tt class="wr">"/"</tt>
+ * character the href will be prefixed with the web application
+ * <tt>context path</tt>.
+ *
+ * @param href the CSS link href attribute
+ */
+ public CssImport(String href) {
+ setHref(href);
+ setAttribute("type", "text/css");
+ setAttribute("rel", "stylesheet");
+ }
+
+ // ------------------------------------------------------ Public Properties
+
+ /**
+ * Returns the Css import HTML tag: <link>.
+ *
+ * @return the Css import HTML tag: <link>
+ */
+ public String getTag() {
+ return "link";
+ }
+
+ /**
+ * This method always return true because CSS import must be unique based on
+ * its <tt>href</tt> attribute. In other words the Page HEAD should only
+ * contain a single CSS import for the specific <tt>href</tt>.
+ *
+ * @see HtmlHeader#isUnique()
+ *
+ * @return true because CSS import must unique based on its <tt>href</tt>
+ * attribute
+ */
+ public boolean isUnique() {
+ return true;
+ }
+
+ /**
+ * Sets the <tt>href</tt> attribute.
+ * <p/>
+ * If the given <tt>href</tt> begins with a <tt class="wr">"/"</tt> character
+ * the href will be prefixed with the web applications <tt>context path</tt>.
+ * Note if the given href is already prefixed with the <tt>context path</tt>,
+ * Click won't add it a second time.
+ *
+ * @param href the new href attribute
+ */
+ public void setHref(String href) {
+ if (href != null) {
+ if (href.charAt(0) == '/') {
+ Context context = getContext();
+ String contextPath = context.getRequest().getContextPath();
+
+ // Guard against adding duplicate context path
+ if (!href.startsWith(contextPath + '/')) {
+ HtmlStringBuffer buffer =
+ new HtmlStringBuffer(contextPath.length() + href.length());
+
+ // Append the context path
+ buffer.append(contextPath);
+ buffer.append(href);
+ href = buffer.toString();
+ }
+ }
+ }
+ setAttribute("href", href);
+ }
+
+ /**
+ * Return the <tt>href</tt> attribute.
+ *
+ * @return the href attribute
+ */
+ public String getHref() {
+ return getAttribute("href");
+ }
+
+ // --------------------------------------------------------- Public Methods
+
+ /**
+ * Render the HTML representation of the CSS import to the specified buffer.
+ *
+ * @param buffer the buffer to render output to
+ */
+ public void render(HtmlStringBuffer buffer) {
+ renderConditionalCommentPrefix(buffer);
+
+ buffer.elementStart(getTag());
+
+ buffer.appendAttribute("id", getId());
+ appendAttributes(buffer);
+
+ buffer.elementEnd();
+
+ 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 (getHref() == null) {
+ throw new IllegalStateException("'href' attribute is not defined.");
+ }
+
+ //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 CssImport)) {
+ return false;
+ }
+
+ //3. Cast the argument to the correct type.
+ CssImport that = (CssImport) o;
+
+ return getHref() == null ? that.getHref() == null
+ : getHref().equals(that.getHref());
+ }
+
+ /**
+ * @see java.lang.Object#hashCode()
+ *
+ * @return a hash code value for this object
+ */
+ public int hashCode() {
+ return new HashCodeBuilder(17, 37).append(getHref()).toHashCode();
+ }
+
+ // ------------------------------------------------ Package Private Methods
+
+ /**
+ * This operation is not supported because CSS imports is always unique
+ * based on their <tt>href</tt> attribute.
+ *
+ * @see HtmlHeader#setUnique(boolean)
+ *
+ * @param unique sets whether the Css import should be unique or not
+ */
+ void setUnique(boolean unique) {
+ throw new UnsupportedOperationException("CssImport is always"
+ + " unique based on the 'href' attribute");
+ }
+}
Added: incubator/click/trunk/click/framework/src/org/apache/click/element/CssStyle.java
URL: http://svn.apache.org/viewvc/incubator/click/trunk/click/framework/src/org/apache/click/element/CssStyle.java?rev=752978&view=auto
==============================================================================
--- incubator/click/trunk/click/framework/src/org/apache/click/element/CssStyle.java (added)
+++ incubator/click/trunk/click/framework/src/org/apache/click/element/CssStyle.java Thu Mar 12 19:20:04 2009
@@ -0,0 +1,241 @@
+/*
+ * 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 org.apache.click.util.HtmlStringBuffer;
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+
+/**
+ *
+ * @author Bob Schellink
+ */
+public class CssStyle extends ResourceElement {
+
+ // -------------------------------------------------------------- Variables
+
+ /** A buffer holding the inline CSS content. */
+ private HtmlStringBuffer content = new HtmlStringBuffer();
+
+ /**
+ * Indicates if the HtmlHeader's content should be wrapped in a CDATA tag.
+ * <b>Note:</b> this property only applies to HtmlHeader imports which contain
+ * <tt>inline</tt> content.
+ */
+ private boolean characterData = false;
+
+ // ------------------------------------------------------------ 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.append(content);
+ }
+ setAttribute("type", "text/css");
+ setAttribute("rel", "stylesheet");
+ }
+
+ // ------------------------------------------------------ Public properties
+
+ /**
+ * Returns the Css HTML tag: <style>.
+ *
+ * @return the Css HTML tag: <style>
+ */
+ public String getTag() {
+ return "style";
+ }
+
+ /**
+ * Return the CSS content buffer.
+ *
+ * @return the CSS content buffer
+ */
+ public HtmlStringBuffer getContent() {
+ return content;
+ }
+
+ /**
+ * Set the CSS content buffer.
+ *
+ * @param content the new content buffer
+ */
+ public void setContent(HtmlStringBuffer content) {
+ this.content = content;
+ }
+
+ /**
+ * Return true if the HtmlHeader's content should be wrapped in CDATA tags,
+ * false otherwise.
+ *
+ * @return true if the HtmlHeader's content should be wrapped in CDATA tags,
+ * false otherwise
+ */
+ public boolean isCharacterData() {
+ return characterData;
+ }
+
+ /**
+ * Sets whether the HtmlHeader's content should be wrapped in CDATA tags or not.
+ *
+ * @param characterData true indicates that the HtmlHeader's content should be
+ * wrapped in CDATA tags, false otherwise
+ */
+ public void setCharacterData(boolean characterData) {
+ this.characterData = characterData;
+ }
+
+ // --------------------------------------------------------- Public Methods
+
+ /**
+ * Append the given CSS string to the content buffer.
+ *
+ * @param content the CSS string to append to the content buffer
+ */
+ public void append(String content) {
+ this.content.append(content);
+ }
+
+ /**
+ * Render the HTML representation of the CSS 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();
+
+ // Render CDATA tag if necessary
+ renderCharacterDataPrefix(buffer);
+
+ buffer.append(getContent());
+
+ renderCharacterDataSuffix(buffer);
+
+ 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();
+ }
+
+ // ------------------------------------------------ Package Private Methods
+
+ /**
+ * Render the CDATA tag prefix to the specified buffer if
+ * {@link #isCharacterData()} returns true. The default value is
+ * <tt>/∗<![CDATA[∗/</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>/∗]]>∗/</tt>.
+ *
+ * @param buffer buffer to append the conditional comment prefix
+ */
+ void renderCharacterDataSuffix(HtmlStringBuffer buffer) {
+ if (isCharacterData()) {
+ buffer.append(" /*]]>*/");
+ }
+ }
+
+ /**
+ * @see HtmlHeader#setUnique(boolean)
+ *
+ * @deprecated use {@link #setId(java.lang.String)} instead
+ *
+ * @param unique sets whether the HtmlHeader import should be unique or not
+ */
+ void setUnique(boolean unique) {
+ super.setUnique(unique);
+
+ // If CSS is unique and ID is not defined, derive the ID from the content
+ if (unique && StringUtils.isBlank(getId()) && getContent().length() > 0) {
+ int hash = getContent().toString().hashCode();
+ setId(Integer.toString(hash));
+ }
+ }
+}
Added: incubator/click/trunk/click/framework/src/org/apache/click/element/Element.java
URL: http://svn.apache.org/viewvc/incubator/click/trunk/click/framework/src/org/apache/click/element/Element.java?rev=752978&view=auto
==============================================================================
--- incubator/click/trunk/click/framework/src/org/apache/click/element/Element.java (added)
+++ incubator/click/trunk/click/framework/src/org/apache/click/element/Element.java Thu Mar 12 19:20:04 2009
@@ -0,0 +1,254 @@
+/*
+ * 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;
+
+/**
+ *
+ * @author Bob Schellink
+ */
+public class Element {
+
+ // -------------------------------------------------------------- Variables
+
+ /** The HtmlHeader attributes Map. */
+ private Map attributes;
+
+ // ------------------------------------------------------ Public properties
+
+ /**
+ * Returns the Element HTML tag, the default value is <tt>null</tt>.
+ * <p/>
+ * Subclasses should override this method and return the correct tag.
+ *
+ * @return this Element HTML tag
+ */
+ public String getTag() {
+ return null;
+ }
+
+ /**
+ * Return the HTML attribute with the given name, or null if the
+ * attribute does not exist.
+ *
+ * @param name the name of link HTML attribute
+ * @return the link HTML attribute
+ */
+ public String getAttribute(String name) {
+ if (hasAttributes()) {
+ return (String) getAttributes().get(name);
+ }
+ return null;
+ }
+
+ /**
+ * Set the Element attribute with the given attribute name and value.
+ *
+ * @param name the attribute name
+ * @param value the attribute value
+ * @throws IllegalArgumentException if name parameter is null
+ */
+ public void setAttribute(String name, String value) {
+ if (name == null) {
+ throw new IllegalArgumentException("Null name parameter");
+ }
+
+ if (value != null) {
+ getAttributes().put(name, value);
+ } else {
+ getAttributes().remove(name);
+ }
+ }
+
+ /**
+ * Return the Element attributes Map.
+ *
+ * @return the Element attributes Map.
+ */
+ public Map getAttributes() {
+ if (attributes == null) {
+ attributes = new HashMap();
+ }
+ return attributes;
+ }
+
+ /**
+ * Return true if the Element has attributes or false otherwise.
+ *
+ * @return true if the Element has attributes on false otherwise
+ */
+ public boolean hasAttributes() {
+ if (attributes != null) {
+ return !attributes.isEmpty();
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Returns true if specified attribute is defined, false otherwise.
+ *
+ * @param name the specified attribute to check
+ * @return true if name is a defined attribute
+ */
+ public boolean hasAttribute(String name) {
+ return hasAttributes() && getAttributes().containsKey(name);
+ }
+
+ /**
+ * Return the "id" attribute value or null if no id is defined.
+ *
+ * @return HTML element identifier attribute "id" value or null if no id
+ * is defined
+ */
+ public String getId() {
+ return getAttribute("id");
+ }
+
+ /**
+ * Set the HTML id attribute for the with the given value.
+ *
+ * @param id the element HTML id attribute value to set
+ */
+ public void setId(String id) {
+ if (id != null) {
+ setAttribute("id", id);
+ } else {
+ getAttributes().remove("id");
+ }
+ }
+
+ // --------------------------------------------------------- Public methods
+
+ /**
+ * Return the thread local Context.
+ *
+ * @return the thread local Context
+ */
+ public Context getContext() {
+ return Context.getThreadLocalContext();
+ }
+
+ /**
+ * Render the HTML representation of the Element to the specified buffer.
+ * <p/>
+ * If {@link #getTag()} returns null, this method will return an empty
+ * string.
+ *
+ * @param buffer the specified buffer to render the Element output to
+ */
+ public void render(HtmlStringBuffer buffer) {
+ if (getTag() == null) {
+ return;
+ }
+ renderTagBegin(getTag(), buffer);
+ renderTagEnd(getTag(), buffer);
+
+ }
+
+ /**
+ * Return the HTML string representation of the Element.
+ *
+ * @return the HTML string representation of the Element
+ */
+ public String toString() {
+ if (getTag() == null) {
+ return "";
+ }
+ HtmlStringBuffer buffer = new HtmlStringBuffer(getElementSizeEst());
+ render(buffer);
+ return buffer.toString();
+ }
+
+ // ------------------------------------------------ Package Private Methods
+
+ /**
+ * Render the specified {@link #getTag() tag} and {@link #getAttributes()}.
+ * <p/>
+ * <b>Please note:</b> the tag will not be closed by this method. This
+ * enables callers of this method to append extra attributes as needed.
+ * <p/>
+ * For example the result of calling:
+ * <pre class="prettyprint">
+ * Field field = new TextField("mytext");
+ * HtmlStringBuffer buffer = new HtmlStringBuffer();
+ * field.renderTagBegin("div", buffer);
+ * </pre>
+ * will be:
+ * <pre class="prettyprint">
+ * <div name="mytext" id="mytext"
+ * </pre>
+ * Note that the tag is not closed.
+ *
+ * @param tagName the name of the tag to render
+ * @param buffer the buffer to append the output to
+ */
+ void renderTagBegin(String tagName, HtmlStringBuffer buffer) {
+ if (tagName == null) {
+ throw new IllegalStateException("Tag cannot be null");
+ }
+
+ buffer.elementStart(tagName);
+
+ buffer.appendAttribute("id", getId());
+ appendAttributes(buffer);
+ }
+
+ /**
+ * Closes the specified {@link #getTag() tag}.
+ *
+ * @param tagName the name of the tag to close
+ * @param buffer the buffer to append the output to
+ */
+ void renderTagEnd(String tagName, HtmlStringBuffer buffer) {
+ buffer.elementEnd();
+ }
+
+ /**
+ * Return the estimated rendered element size in characters.
+ *
+ * @return the estimated rendered element size in characters
+ */
+ int getElementSizeEst() {
+ int size = 0;
+ if (getTag() != null && hasAttributes()) {
+ //length of the markup -> </> == 3
+ //1 * tag.length()
+ size += 3 + getTag().length();
+ //using 20 as an estimate
+ size += 20 * getAttributes().size();
+ }
+ return size;
+ }
+
+ /**
+ * Append all the Element attributes to the specified buffer.
+ *
+ * @param buffer the specified buffer to append all the attributes
+ */
+ void appendAttributes(HtmlStringBuffer buffer) {
+ if (hasAttributes()) {
+ buffer.appendAttributes(attributes);
+ }
+ }
+}
Added: incubator/click/trunk/click/framework/src/org/apache/click/element/JsImport.java
URL: http://svn.apache.org/viewvc/incubator/click/trunk/click/framework/src/org/apache/click/element/JsImport.java?rev=752978&view=auto
==============================================================================
--- incubator/click/trunk/click/framework/src/org/apache/click/element/JsImport.java (added)
+++ incubator/click/trunk/click/framework/src/org/apache/click/element/JsImport.java Thu Mar 12 19:20:04 2009
@@ -0,0 +1,191 @@
+/*
+ * 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 org.apache.click.Context;
+import org.apache.click.util.HtmlHeader;
+import org.apache.click.util.HtmlStringBuffer;
+import org.apache.click.util.JavascriptImport;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+
+/**
+ *
+ * @author Bob Schellink
+ */
+public class JsImport extends ResourceElement {
+
+ // ----------------------------------------------------------- Constructors
+
+ /**
+ * Constructs a new JavascriptImport.
+ */
+ public JsImport() {
+ this(null);
+ }
+
+ /**
+ * Construct a new JavascriptImport with the specified <tt>src</tt> attribute.
+ * <p/>
+ * <b>Please note</b> if the given <tt>src</tt> begins with a <tt class="wr">"/"</tt>
+ * character the src will be prefixed with the web application
+ * <tt>context path</tt>.
+ *
+ * @param src the Javascript src attribute
+ */
+ public JsImport(String src) {
+ setSrc(src);
+ setAttribute("type", "text/javascript");
+ }
+
+ // ------------------------------------------------------ Public properties
+
+ /**
+ * Returns the Css import HTML tag: <script>.
+ *
+ * @return the Css import HTML tag: <script>
+ */
+ public String getTag() {
+ return "script";
+ }
+
+ /**
+ * This method always return true because JavaScript import must be unique
+ * based on its <tt>src</tt> attribute. In other words the Page HEAD should
+ * only contain a single JavaScript import for the specific <tt>src</tt>.
+ *
+ * @see HtmlHeader#isUnique()
+ *
+ * @return true because JavaScript import must unique based on its
+ * <tt>src</tt> attribute
+ */
+ public boolean isUnique() {
+ return true;
+ }
+
+ /**
+ * Sets the <tt>src</tt> attribute.
+ * <p/>
+ * If the given <tt>src</tt> begins with a <tt class="wr">"/"</tt> character
+ * the sr will be prefixed with the web application <tt>context path</tt>.
+ * Note if the given src is already prefixed with the <tt>context path</tt>,
+ * Click won't add it a second time.
+ *
+ * @param src the new src attribute
+ */
+ public void setSrc(String src) {
+ if (src != null) {
+ if (src.charAt(0) == '/') {
+ Context context = getContext();
+ String contextPath = context.getRequest().getContextPath();
+
+ // Guard against adding duplicate context path
+ if (!src.startsWith(contextPath + '/')) {
+ HtmlStringBuffer buffer =
+ new HtmlStringBuffer(contextPath.length() + src.length());
+
+ // Append the context path
+ buffer.append(contextPath);
+ buffer.append(src);
+ src = buffer.toString();
+ }
+ }
+ }
+ setAttribute("src", src);
+ }
+
+ /**
+ * Return the <tt>src</tt> attribute.
+ *
+ * @return the src attribute
+ */
+ public String getSrc() {
+ return getAttribute("src");
+ }
+
+ // ------------------------------------------------ Package Private Methods
+
+ /**
+ * Render the HTML representation of the JavaScript import to the specified
+ * buffer.
+ *
+ * @param buffer the buffer to render output to
+ */
+ public void render(HtmlStringBuffer buffer) {
+ renderConditionalCommentPrefix(buffer);
+
+ buffer.elementStart(getTag());
+
+ buffer.appendAttribute("id", getId());
+ appendAttributes(buffer);
+
+ buffer.closeTag();
+
+ 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) {
+ //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 JavascriptImport)) {
+ return false;
+ }
+
+ //3. Cast the argument to the correct type.
+ JavascriptImport that = (JavascriptImport) o;
+
+ return getSrc() == null ? that.getSrc() == null
+ : getSrc().equals(that.getSrc());
+ }
+
+ /**
+ * @see java.lang.Object#hashCode()
+ *
+ * @return a hash code value for this object
+ */
+ public int hashCode() {
+ return new HashCodeBuilder(17, 37).append(getSrc()).toHashCode();
+ }
+
+ // ------------------------------------------------ Package Private Methods
+
+ /**
+ * This operation is not supported because JavaScript imports is always
+ * unique based on their <tt>src</tt> attribute.
+ *
+ * @see HtmlHeader#setUnique(boolean)
+ *
+ * @param unique sets whether the JavaScript import should be unique or not
+ */
+ void setUnique(boolean unique) {
+ throw new UnsupportedOperationException("JavascriptImport is always"
+ + " unique based on the 'src' attribute");
+ }
+}
Added: incubator/click/trunk/click/framework/src/org/apache/click/element/JsScript.java
URL: http://svn.apache.org/viewvc/incubator/click/trunk/click/framework/src/org/apache/click/element/JsScript.java?rev=752978&view=auto
==============================================================================
--- incubator/click/trunk/click/framework/src/org/apache/click/element/JsScript.java (added)
+++ incubator/click/trunk/click/framework/src/org/apache/click/element/JsScript.java Thu Mar 12 19:20:04 2009
@@ -0,0 +1,244 @@
+/*
+ * 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 org.apache.click.util.HtmlHeader;
+import org.apache.click.util.HtmlStringBuffer;
+import org.apache.click.util.Javascript;
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+
+/**
+ *
+ * @author Bob Schellink
+ */
+public class JsScript extends ResourceElement {
+
+ // -------------------------------------------------------------- Variables
+
+ /** A buffer holding the inline CSS content. */
+ private HtmlStringBuffer content = new HtmlStringBuffer();
+
+ /**
+ * Indicates if the HtmlHeader's content should be wrapped in a CDATA tag.
+ * <b>Note:</b> this property only applies to HtmlHeader imports which contain
+ * <tt>inline</tt> content.
+ */
+ private boolean characterData = false;
+
+ // ----------------------------------------------------------- Constructors
+
+ /**
+ * Construct a new inline Javascript element.
+ */
+ public JsScript() {
+ this(null);
+ }
+
+ /**
+ * Construct a new inline Javascript element with the given content.
+ *
+ * @param content the Javascript content
+ */
+ public JsScript(String content) {
+ if (content != null) {
+ this.content.append(content);
+ }
+ setAttribute("type", "text/javascript");
+ }
+
+ // ------------------------------------------------------ Public Properties
+
+ /**
+ * Returns the Javascript HTML tag: <script>.
+ *
+ * @return the Javascript HTML tag: <script>
+ */
+ public String getTag() {
+ return "script";
+ }
+
+ /**
+ * Return the Javascript content buffer.
+ *
+ * @return the Javascript content buffer
+ */
+ public HtmlStringBuffer getContent() {
+ return content;
+ }
+
+ /**
+ * Set the Javascript content buffer.
+ *
+ * @param content the new content buffer
+ */
+ public void setContent(HtmlStringBuffer content) {
+ this.content = content;
+ }
+
+ /**
+ * Return true if the HtmlHeader's content should be wrapped in CDATA tags,
+ * false otherwise.
+ *
+ * @return true if the HtmlHeader's content should be wrapped in CDATA tags,
+ * false otherwise
+ */
+ public boolean isCharacterData() {
+ return characterData;
+ }
+
+ /**
+ * Sets whether the HtmlHeader's content should be wrapped in CDATA tags or not.
+ *
+ * @param characterData true indicates that the HtmlHeader's content should be
+ * wrapped in CDATA tags, false otherwise
+ */
+ public void setCharacterData(boolean characterData) {
+ this.characterData = characterData;
+ }
+
+ // --------------------------------------------------------- Public Methods
+
+ /**
+ * Append the given Javascript string to the content buffer.
+ *
+ * @param content the Javascript string to append to the content
+ * buffer
+ */
+ public void append(String content) {
+ this.content.append(content);
+ }
+
+ /**
+ * Render the HTML representation of the JavaScript 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();
+
+ // Render CDATA tag if necessary
+ renderCharacterDataPrefix(buffer);
+
+ buffer.append(getContent());
+
+ renderCharacterDataSuffix(buffer);
+
+ 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 Javascript)) {
+ return false;
+ }
+
+ //3. Cast the argument to the correct type.
+ Javascript that = (Javascript) 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();
+ }
+
+ // ------------------------------------------------ Package Private Methods
+
+ /**
+ * Render the CDATA tag prefix to the specified buffer if
+ * {@link #isCharacterData()} returns true. The default value is
+ * <tt>/∗<![CDATA[∗/</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>/∗]]>∗/</tt>.
+ *
+ * @param buffer buffer to append the conditional comment prefix
+ */
+ void renderCharacterDataSuffix(HtmlStringBuffer buffer) {
+ if (isCharacterData()) {
+ buffer.append(" /*]]>*/");
+ }
+ }
+
+ /**
+ * @see HtmlHeader#setUnique(boolean)
+ *
+ * @deprecated use {@link #setId(java.lang.String)} instead
+ *
+ * @param unique sets whether the HtmlHeader import should be unique or not
+ */
+ void setUnique(boolean unique) {
+ super.setUnique(unique);
+
+ // If CSS is unique and ID is not defined, derive the ID from the content
+ if (unique && StringUtils.isBlank(getId()) && getContent().length() > 0) {
+ int hash = Math.abs(getContent().toString().hashCode());
+ setId(Integer.toString(hash));
+ }
+ }
+}
Added: incubator/click/trunk/click/framework/src/org/apache/click/element/ResourceElement.java
URL: http://svn.apache.org/viewvc/incubator/click/trunk/click/framework/src/org/apache/click/element/ResourceElement.java?rev=752978&view=auto
==============================================================================
--- incubator/click/trunk/click/framework/src/org/apache/click/element/ResourceElement.java (added)
+++ incubator/click/trunk/click/framework/src/org/apache/click/element/ResourceElement.java Thu Mar 12 19:20:04 2009
@@ -0,0 +1,175 @@
+/*
+ * 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 org.apache.click.util.HtmlStringBuffer;
+import org.apache.commons.lang.StringUtils;
+
+/**
+ *
+ * @author Bob Schellink
+ */
+public class ResourceElement extends Element {
+
+ // -------------------------------------------------------------- Constants
+
+ /**
+ * A predefined conditional comment to test if browser is IE. Value:
+ * <tt>[if IE]</tt>.
+ */
+ public static final String IF_IE = "[if IE]";
+
+ /**
+ * A predefined conditional comment to test if browser is less than IE7.
+ * Value: <tt>[if lt IE 7]</tt>.
+ */
+ public static final String IF_LESS_THAN_IE7 = "[if lt IE 7]";
+
+ /**
+ * A predefined conditional comment to test if browser is IE7. Value:
+ * <tt>[if IE 7]</tt>.
+ */
+ public static final String IF_IE7 = "[if IE 7]";
+
+ // -------------------------------------------------------------- Variables
+
+ /** The Internet Explorer conditional comment to wrap the HtmlHeader import with. */
+ private String conditionalComment;
+
+ /**
+ * Indicates if Click should ensure the import is unique, default value is
+ * <tt>false</tt>. <b>Note:</b> subclasses of HtmlHeader have different rules to
+ * determine if unique should be true or false.
+ */
+ private boolean unique = false;
+
+ // ------------------------------------------------------ Public properties
+
+ /**
+ * Return true if the HtmlHeader should be unique, false otherwise. The default
+ * value is <tt>true</tt> if the {@link #getId() ID} attribute is defined,
+ * false otherwise.
+ *
+ * @return true if the HtmlHeader should be unique, false otherwise.
+ */
+ public boolean isUnique() {
+ String id = getId();
+
+ // If id is defined, import will be any duplicate import found will be
+ // filtered out
+ if (StringUtils.isNotBlank(id)) {
+ return true;
+ }
+ return unique;
+ }
+
+ /**
+ * Return Internal Explorer's <tt>conditional comment</tt> to wrap the HtmlHeader
+ * import with.
+ *
+ * @return Internal Explorer's conditional comment to wrap the HtmlHeader import
+ * with.
+ */
+ public String getConditionalComment() {
+ return conditionalComment;
+ }
+
+ /**
+ * Set Internet Explorer's conditional comment to wrap the HtmlHeader import with.
+ *
+ * @param conditionalComment Internet Explorer's conditional comment to wrap
+ * the HtmlHeader import with
+ */
+ public void setConditionalComment(String conditionalComment) {
+ this.conditionalComment = conditionalComment;
+ }
+
+ // --------------------------------------------------------- Public methods
+
+ public void render(HtmlStringBuffer buffer) {
+ renderConditionalCommentPrefix(buffer);
+
+ if (getTag() == null) {
+ return;
+ }
+ renderTagBegin(getTag(), buffer);
+ renderTagEnd(getTag(), buffer);
+
+ renderConditionalCommentSuffix(buffer);
+ }
+
+ // ------------------------------------------------ Package Private Methods
+
+ /**
+ * Render the {@link #getConditionalComment() conditional comment} prefix
+ * to the specified buffer. If the conditional comment is not defined this
+ * method won't append to the buffer.
+ *
+ * @param buffer buffer to append the conditional comment prefix
+ */
+ void renderConditionalCommentPrefix(HtmlStringBuffer buffer) {
+ String conditional = getConditionalComment();
+
+ // Render IE conditional comment
+ if (StringUtils.isNotBlank(conditional)) {
+ buffer.append("<!--").append(conditional).append(">\n");
+ }
+ }
+
+ /**
+ * Render the {@link #getConditionalComment() conditional comment} suffix
+ * to the specified buffer. If the conditional comment is not defined this
+ * method won't append to the buffer.
+ *
+ * @param buffer buffer to append the conditional comment suffix
+ */
+ void renderConditionalCommentSuffix(HtmlStringBuffer buffer) {
+ String conditional = getConditionalComment();
+
+ // Close IE conditional comment
+ if (StringUtils.isNotBlank(conditional)) {
+ buffer.append("\n<![endif]-->");
+ }
+ }
+
+ /**
+ * This method provides backwards compatibility with the String based
+ * HTML imports, to indicate whether Javascript and CSS must be unique
+ * or not. The replacement functionality is provided by the html
+ * {@link #setId(java.lang.String) ID} attribute.
+ * <p/>
+ * This property is *not* for public use and will be removed in a future
+ * release. This property is only set from PageImports.
+ *
+ * @deprecated use {@link #setId(java.lang.String)} instead
+ *
+ * @param unique sets whether the HtmlHeader import should be unique or not
+ */
+ void setUnique(boolean unique) {
+ String id = getId();
+
+ // If id is defined, unique property cannot be set to false
+ if (StringUtils.isNotBlank(id) && !unique) {
+ throw new IllegalArgumentException("Cannot set unique property"
+ + " to 'false' because an 'ID' attribute has been defined"
+ + " which indicates the import should be unique.");
+ }
+ this.unique = unique;
+ }
+}