Skip to content

Commit

Permalink
- update to wicket 6.13
Browse files Browse the repository at this point in the history
- reformat code and add some documentation
  • Loading branch information
l0rdn1kk0n committed Jan 21, 2014
1 parent 9e1f45c commit c4008b5
Show file tree
Hide file tree
Showing 22 changed files with 740 additions and 864 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
language: java
jdk:
- oraclejdk7
- openjdk6
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@ Add maven dependency:
<dependency>
<groupId>de.agilecoders.wicket.webjars</groupId>
<artifactId>wicket-webjars</artifactId>
<version>0.3.3</version>
<version>0.3.4</version>
</dependency>

<dependency>
<groupId>de.agilecoders.wicket.webjars</groupId>
<artifactId>vfs-support</artifactId>
<version>0.3.3</version>
<version>0.3.4</version>
</dependency>
```

Expand All @@ -38,6 +38,8 @@ Installation:
public void init() {
super.init();

// install installs 2 default collector instances (FileAssetPathCollector(WEBJARS_PATH_PREFIX), JarAssetPathCollector)
// and a webjars resource finder.
WicketWebjars.install(this);

// register vfs collector to use webjars on jboss (please add maven dependency too)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
package de.agilecoders.wicket.webjars;

import com.google.common.collect.Lists;
import de.agilecoders.wicket.webjars.collectors.AssetPathCollector;
import de.agilecoders.wicket.webjars.collectors.FileAssetPathCollector;
import de.agilecoders.wicket.webjars.collectors.JarAssetPathCollector;

import java.io.IOException;
import java.net.URL;
import java.util.Collection;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.regex.Pattern;

/**
* Locate WebJar assets. The class is thread safe.
*/
public class WebJarAssetLocator {

/**
* The webjar package name.
*/
public static final String WEBJARS_PACKAGE = "META-INF.resources.webjars";

/**
* The path to where webjar resources live.
*/
public static final String WEBJARS_PATH_PREFIX = "META-INF/resources/webjars";

private static final Set<AssetPathCollector> collectors = new HashSet<AssetPathCollector>();

static {
registerCollector(new FileAssetPathCollector(WEBJARS_PATH_PREFIX), new JarAssetPathCollector());
}

/**
* registers an additional collector
*
* @param collectorArr the collectors to register
*/
public static void registerCollector(AssetPathCollector... collectorArr) {
synchronized (collectors) {
collectors.addAll(Lists.newArrayList(collectorArr));
}
}

/*
* Return all {@link URL}s defining {@value VfsAwareWebJarAssetLocator#WEBJARS_PATH_PREFIX} directory, either identifying JAR files or plain
* directories.
*/
private static Set<URL> listWebjarsParentURLs(final ClassLoader[] classLoaders) {
final Set<URL> urls = new HashSet<URL>();
for (final ClassLoader classLoader : classLoaders) {
try {
final Enumeration<URL> enumeration = classLoader.getResources(WEBJARS_PATH_PREFIX);
while (enumeration.hasMoreElements()) {
urls.add(enumeration.nextElement());
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
return urls;
}

/*
* Return all of the resource paths filtered given an expression and a list of class loaders.
*/
private static Set<String> getAssetPaths(final Pattern filterExpr, final ClassLoader... classLoaders) {
final Set<String> assetPaths = new HashSet<String>();
final Set<URL> urls = listWebjarsParentURLs(classLoaders);

for (final URL url : urls) {
for (AssetPathCollector collector : collectors) {
if (collector.accept(url)) {
assetPaths.addAll(collector.collect(url, filterExpr));
}
}
}

return assetPaths;
}

/**
* Return a map that can be used to perform index lookups of partial file paths. This index constitutes a key that is the reverse form of the path
* it relates to. Thus if a partial lookup needs to be performed from the rightmost path components then the key to access can be expressed easily
* e.g. the path "a/b" would be the map tuple "b/a" -> "a/b". If we need to look for an asset named "a" without knowing the full path then we can
* perform a partial lookup on the sorted map.
*
* @param filterExpr the regular expression to be used to filter resources that will be included in the index.
* @param classLoaders the class loaders to be considered for loading the resources from.
* @return the index.
*/
public static SortedMap<String, String> getFullPathIndex(final Pattern filterExpr, final ClassLoader... classLoaders) {

final Set<String> assetPaths = getAssetPaths(filterExpr, classLoaders);

final SortedMap<String, String> assetPathIndex = new TreeMap<String, String>();
for (final String assetPath : assetPaths) {
assetPathIndex.put(reversePath(assetPath), assetPath);
}

return assetPathIndex;
}

/*
* Make paths like aa/bb/cc = cc/bb/aa.
*/
private static String reversePath(String assetPath) {
final String[] assetPathComponents = assetPath.split("/");
final StringBuilder reversedAssetPath = new StringBuilder();
for (int i = assetPathComponents.length - 1; i >= 0; --i) {
if (reversedAssetPath.length() > 0) {
reversedAssetPath.append('/');
}
reversedAssetPath.append(assetPathComponents[i]);
}
return reversedAssetPath.toString();
}

final SortedMap<String, String> fullPathIndex;

/**
* Convenience constructor that will form a locator for all resources on the current class path.
*/
public WebJarAssetLocator() {
this(getFullPathIndex(Pattern.compile(".*"), WebJarAssetLocator.class.getClassLoader()));
}

/**
* Establish a locator given an index that it should use.
*
* @param fullPathIndex the index to use.
*/
public WebJarAssetLocator(final SortedMap<String, String> fullPathIndex) {
this.fullPathIndex = fullPathIndex;
}

private String throwNotFoundException(final String partialPath) {
throw new IllegalArgumentException(partialPath + " could not be found. Make sure you've added the corresponding WebJar and please check for typos.");
}

private String throwMultipleMatchesException(final String partialPath) {
throw new IllegalArgumentException("Multiple matches found for " + partialPath
+ ". Please provide a more specific path, for example by including a version number.");
}

/**
* Given a distinct path within the WebJar index passed in return the full path of the resource.
*
* @param partialPath the path to return e.g. "jquery.js" or "abc/someother.js". This must be a distinct path within the index passed in.
* @return a fully qualified path to the resource.
*/
public String getFullPath(final String partialPath) {

final String reversePartialPath = reversePath(partialPath);

final SortedMap<String, String> fullPathTail = fullPathIndex.tailMap(reversePartialPath);

if (fullPathTail.size() == 0) {
throwNotFoundException(partialPath);
}

final Iterator<Entry<String, String>> fullPathTailIter = fullPathTail.entrySet().iterator();
final Entry<String, String> fullPathEntry = fullPathTailIter.next();
if (!fullPathEntry.getKey().startsWith(reversePartialPath)) {
throwNotFoundException(partialPath);
}
final String fullPath = fullPathEntry.getValue();

if (fullPathTailIter.hasNext() && fullPathTailIter.next().getKey().startsWith(reversePartialPath)) {
throwMultipleMatchesException(reversePartialPath);
}

return fullPath;
}

public SortedMap<String, String> getFullPathIndex() {
return fullPathIndex;
}

/**
* List assets within a folder.
*
* @param folderPath the root path to the folder. Must begin with '/'.
* @return a set of folder paths that match.
*/
public Set<String> listAssets(final String folderPath) {
final Collection<String> allAssets = fullPathIndex.values();
final Set<String> assets = new HashSet<String>();
final String prefix = WEBJARS_PATH_PREFIX + folderPath;
for (final String asset : allAssets) {
if (asset.startsWith(prefix)) {
assets.add(asset);
}
}
return assets;
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
package de.agilecoders.wicket.webjars.util;
package de.agilecoders.wicket.webjars;

import de.agilecoders.wicket.webjars.collectors.AssetPathCollector;
import de.agilecoders.wicket.webjars.util.file.WebjarsResourceFinder;

import org.apache.wicket.Application;
import org.apache.wicket.util.file.IResourceFinder;
import org.apache.wicket.util.lang.Args;
import org.webjars.WebJarAssetLocator;

import java.util.List;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,27 @@
import java.util.regex.Pattern;

/**
* TODO miha: document class purpose
*
* An {@link de.agilecoders.wicket.webjars.collectors.AssetPathCollector} collects webjars assets from
* an url/classpath/disc and so on depending on the protocol that is used.
*
* @author miha
*/
public interface AssetPathCollector {

boolean accept(URL url);
/**
* whether this collector supports given url (especially protocol)
*
* @param url the url to webjars asset
* @return true, if given protocol is accepted
*/
boolean accept(URL url);

Collection<String> collect(URL url, Pattern filterExpr);
/**
* collects all webjars assets on given url.
*
* @param url the path to webjars assets
* @param filterExpr a filter that must be applied on all found assets.
* @return a collection of webjars assets on given {@code url} that matches given {@code filterExpr}
*/
Collection<String> collect(URL url, Pattern filterExpr);
}
Loading

0 comments on commit c4008b5

Please sign in to comment.