package ro.isdc.wro.model.resource.processor.support;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.lang3.Validate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ro.isdc.wro.util.WroUtil;
/**
* Encapsulates the matcher creation for css backround url's detection. Useful to isolate unit tests.
*
* @author Alex Objelean
* @created 20 Feb 2013
* @since 1.6.3
*/
public class CssUrlInspector {
private static final Logger LOG = LoggerFactory.getLogger(CssUrlInspector.class);
private static final Pattern PATTERN = Pattern.compile(WroUtil.loadRegexpWithKey("cssUrlRewrite"));
public final String findAndReplace(final String content, final ItemHandler handler) {
final Matcher matcher = getMatcher(content);
final StringBuffer sb = new StringBuffer();
while (matcher.find()) {
// Do not process @import statements
/**
* The url found inside @import statement should not be matched. This cannot be solved using regexp only because
* of some limitations with negative look-around.
*/
final String cssStatement = matcher.group();
LOG.debug("Matched group: {}", cssStatement);
if (!new CssImportInspector(cssStatement).containsImport()) {
LOG.debug("No @import detected");
final String originalDeclaration = getOriginalDeclaration(matcher);
final String originalUrl = getOriginalUrl(matcher);
LOG.debug("originalDeclaration: {}", originalDeclaration);
LOG.debug("originalUrl: {}", originalUrl);
Validate.notNull(originalUrl);
matcher.appendReplacement(sb, handler.replace(originalDeclaration, originalUrl));
}
}
matcher.appendTail(sb);
return sb.toString();
}
/**
* @return the {@link Matcher} for processed css content.
*/
protected Matcher getMatcher(final String content) {
return PATTERN.matcher(content);
}
/**
* @param matcher
* the {@link Matcher} used to find url occurances.
* @return the string representing entire css declaration containing the url.
*/
protected String getOriginalDeclaration(final Matcher matcher) {
return matcher.group(0);
}
/**
* @param matcher
* the {@link Matcher} used to find url occurances.
* @return the url found in css declaration.
*/
protected String getOriginalUrl(final Matcher matcher) {
/**
* index of the group containing an url inside a declaration of this form:
*
* <pre>
* body {
* filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../images/tabs/tabContent.png', sizingMethod='scale' );
* }
* </pre>
*
* or
*
* <pre>
* @font-face {
* src: url(btn_icons.png);
* }
* </pre>
*/
final String groupA = matcher.group(1);
/**
* index of the group containing an url inside a declaration of this form:
*
* <pre>
* body {
* background: #B3B3B3 url(img.gif);
* color:red;
* }
* </pre>
*/
final String originalUrl = groupA != null ? groupA : matcher.group(2);
return originalUrl;
}
/**
* The handler invoked for each found occurrence of url in parsed css.
*/
public static interface ItemHandler {
String replace(String originalDeclaration, String originalUrl);
}
}