com.phloc.css.utils.CSSURLHelper Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of phloc-css-jdk5 Show documentation
Show all versions of phloc-css-jdk5 Show documentation
phloc CSS parser an other components
The newest version!
/**
* Copyright (C) 2006-2014 phloc systems
* http://www.phloc.com
* office[at]phloc[dot]com
*
* Licensed 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 com.phloc.css.utils;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;
import com.phloc.commons.ValueEnforcer;
import com.phloc.commons.annotations.Nonempty;
import com.phloc.commons.annotations.PresentForCodeCoverage;
import com.phloc.commons.string.StringHelper;
import com.phloc.commons.url.ISimpleURL;
import com.phloc.css.parser.ParseUtils;
import com.phloc.css.propertyvalue.CCSSValue;
/**
* Provides URL handling sanity methods.
*
* @author Philip Helger
*/
@Immutable
public final class CSSURLHelper
{
/** For compatibility reasons, this is set to false */
public static final boolean DEFAULT_QUOTE_URLS = false;
@SuppressWarnings ("unused")
@PresentForCodeCoverage
private static final CSSURLHelper s_aInstance = new CSSURLHelper ();
private CSSURLHelper ()
{}
/**
* Check if the passed CSS value is an URL value. This is either a URL
* starting with "url(" or it is the string "none".
*
* @param sValue
* The value to be checked.
* @return true
if the passed value starts with "url(" and ends
* with ")" - false
otherwise.
*/
public static boolean isURLValue (@Nullable final String sValue)
{
final String sRealValue = StringHelper.trim (sValue);
if (StringHelper.hasNoText (sRealValue))
return false;
if (sRealValue.equals (CCSSValue.NONE))
return true;
// 5 = "url(".length () + ")".length
return sRealValue.length () > 5 &&
sRealValue.startsWith (CCSSValue.PREFIX_URL_OPEN) &&
sRealValue.endsWith (CCSSValue.SUFFIX_URL_CLOSE);
}
/**
* Extract the real URL contained in a CSS URL value.
*
* @param sValue
* The value containing the CSS value
* @return null
if the passed value is not an URL value
* @see #isURLValue
*/
@Nullable
public static String getURLValue (@Nullable final String sValue)
{
if (isURLValue (sValue))
{
return ParseUtils.trimUrl (sValue);
}
return null;
}
/**
* Surround the passed URL with the CSS "url(...)"
*
* @param aURL
* URL to be wrapped. May not be null
.
* @param bQuoteURL
* if true
single quotes are added around the URL
* @return url(sURL)
or url('sURL')
*/
@Nonnull
@Nonempty
public static String getAsCSSURL (@Nonnull final ISimpleURL aURL, final boolean bQuoteURL)
{
ValueEnforcer.notNull (aURL, "URL");
return getAsCSSURL (aURL.getAsString (), bQuoteURL);
}
/**
* Check if the passed character is a valid character inside a URL. Characters
* for which this method returns false
must be escaped!
*
* @param c
* The character to be checked.
* @return true
if the passed character can be directly contained
* inside a URL, false
otherwise if the character needs
* to be escaped.
*/
public static boolean isValidCSSURLChar (final char c)
{
return c == '!' ||
c == '#' ||
c == '$' ||
c == '%' ||
c == '&' ||
(c >= '*' && c <= '[') ||
(c >= ']' && c <= '~') ||
(c >= '\u0080' && c <= '\uffff');
}
/**
* Check if any character inside the passed URL needs escaping.
*
* @param sURL
* The URL to be checked. May not be null
.
* @return true
if any of the contained characters needs
* escaping, false
if the URL can be used as is.
*/
public static boolean isCSSURLRequiringQuotes (@Nonnull final String sURL)
{
ValueEnforcer.notNull (sURL, "URL");
for (final char c : sURL.toCharArray ())
if (!isValidCSSURLChar (c))
return true;
return false;
}
/**
* Internal method to escape a CSS URL. Because this method is only called for
* quoted URLs, only the quote character itself needs to be quoted.
*
* @param sURL
* The URL to be escaped. May not be null
.
* @param cQuoteChar
* The quote char that is used. Either '\'' or '"'
* @return The escaped string. Never null
.
*/
@Nonnull
@Nonempty
public static String getEscapedCSSURL (@Nonnull final String sURL, final char cQuoteChar)
{
ValueEnforcer.notNull (sURL, "URL");
if (sURL.indexOf (cQuoteChar) < 0 && sURL.indexOf (ParseUtils.URL_ESCAPE_CHAR) < 0)
{
// Found nothing to quote
return sURL;
}
final StringBuilder aSB = new StringBuilder (sURL.length () * 2);
for (final char c : sURL.toCharArray ())
{
// Escape the quote char and the escape char itself
if (c == cQuoteChar || c == ParseUtils.URL_ESCAPE_CHAR)
aSB.append (ParseUtils.URL_ESCAPE_CHAR);
aSB.append (c);
}
return aSB.toString ();
}
/**
* Surround the passed URL with the CSS "url(...)". When the passed URL
* contains characters that require quoting, quotes are automatically added!
*
* @param sURL
* URL to be wrapped. May neither be null
nor empty.
* @param bForceQuoteURL
* if true
single quotes are added around the URL
* @return url(sURL)
or url('sURL')
*/
@Nonnull
@Nonempty
public static String getAsCSSURL (@Nonnull @Nonempty final String sURL, final boolean bForceQuoteURL)
{
ValueEnforcer.notEmpty (sURL, "URL");
final StringBuilder aSB = new StringBuilder (CCSSValue.PREFIX_URL_OPEN);
final boolean bAreQuotesRequired = bForceQuoteURL || isCSSURLRequiringQuotes (sURL);
if (bAreQuotesRequired)
{
// Determine the best quote char to use - default to '\'' for backwards
// compatibility
final int nIndexSingleQuote = sURL.indexOf ('\'');
final int nIndexDoubleQuote = sURL.indexOf ('"');
final char cQuote = nIndexSingleQuote >= 0 && nIndexDoubleQuote < 0 ? '"' : '\'';
// Append the quoted and escaped URL
aSB.append (cQuote).append (getEscapedCSSURL (sURL, cQuote)).append (cQuote);
}
else
{
// No quotes needed
aSB.append (sURL);
}
return aSB.append (CCSSValue.SUFFIX_URL_CLOSE).toString ();
}
}