package ro.isdc.wro.extensions.locator; import static java.lang.String.format; import static org.apache.commons.lang3.Validate.notNull; import java.io.IOException; import java.io.InputStream; import java.util.regex.Pattern; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.webjars.WebJarAssetLocator; import ro.isdc.wro.model.resource.locator.ClasspathUriLocator; import ro.isdc.wro.model.resource.locator.UriLocator; import ro.isdc.wro.model.resource.locator.support.LocatorProvider; import ro.isdc.wro.model.resource.locator.wildcard.DefaultWildcardStreamLocator; /** * Locator responsible for locating webjar resources. A webjar resource is a classpath resource respecting a certain * standard. <a href="http://www.webjars.org/">Read more</a> about webjars. * <p/> * This locator uses the following prefix to identify a locator capable of handling webjar resources: * <code>webjar:</code> * * @author Alex Objelean * @created 6 Jan 2013 * @since 1.6.2 */ public class WebjarUriLocator implements UriLocator { private static final Logger LOG = LoggerFactory.getLogger(WebjarUriLocator.class); /** * Alias used to register this locator with {@link LocatorProvider}. */ public static final String ALIAS = "webjar"; /** * Prefix of the resource uri used to check if the resource can be read by this {@link UriLocator} implementation. */ public static final String PREFIX = format("%s:", ALIAS); private final UriLocator classpathLocator = new ClasspathUriLocator(); private final WebJarAssetLocator webjarAssetLocator = newWebJarAssetLocator(); /** * @return an instance of {@link WebJarAssetLocator} to be used for identifying the fully qualified name of resources * based on provided partial path. */ private WebJarAssetLocator newWebJarAssetLocator() { return new WebJarAssetLocator(WebJarAssetLocator.getFullPathIndex( Pattern.compile(".*"), Thread.currentThread().getContextClassLoader())); } /** * @return the uri which is acceptable by this locator. */ public static String createUri(final String path) { notNull(path); return PREFIX + path; } /** * {@inheritDoc} */ @Override public InputStream locate(final String uri) throws IOException { LOG.debug("locating: {}", uri); try { final String fullpath = webjarAssetLocator.getFullPath(extractPath(uri)); return classpathLocator.locate(ClasspathUriLocator.createUri(fullpath)); } catch (final Exception e) { throw new IOException("No webjar with uri: " + uri + " available.", e); } } /** * Replaces the protocol specific prefix and removes the query path if it exist, since it should not be accepted. */ private String extractPath(final String uri) { return DefaultWildcardStreamLocator.stripQueryPath(uri.replace(PREFIX, "")); } /** * {@inheritDoc} */ @Override public boolean accept(final String uri) { return uri.trim().startsWith(PREFIX); } }