net.jawr.web.resource.bundle.JoinableResourceBundleImpl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jawr-core Show documentation
Show all versions of jawr-core Show documentation
Javascript/CSS bundling and compressing tool for java web apps.
By using jawr resources are automatically bundled together and optionally minified and gzipped.
Jawr provides tag libraries to reference a generated bundle either by id or by using the name of any of its members.
The newest version!
/**
* Copyright 2007-2016 Jordi Hernández Sellés, Ibrahim Chaehoi
*
* 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 net.jawr.web.resource.bundle;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.concurrent.ConcurrentHashMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import net.jawr.web.resource.bundle.factory.util.PathNormalizer;
import net.jawr.web.resource.bundle.generator.GeneratorRegistry;
import net.jawr.web.resource.bundle.iterator.BundlePath;
import net.jawr.web.resource.bundle.mappings.BundlePathMapping;
import net.jawr.web.resource.bundle.mappings.BundlePathMappingBuilder;
import net.jawr.web.resource.bundle.mappings.FilePathMapping;
import net.jawr.web.resource.bundle.mappings.PathMapping;
import net.jawr.web.resource.bundle.postprocess.ResourceBundlePostProcessor;
import net.jawr.web.resource.bundle.variant.VariantSet;
import net.jawr.web.resource.bundle.variant.VariantUtils;
import net.jawr.web.resource.handler.reader.ResourceReaderHandler;
import net.jawr.web.util.StringUtils;
/**
* Basic implementation of JoinableResourceBundle.
*
* @author Jordi Hernández Sellés
* @author Ibrahim Chaehoi
*
*/
public class JoinableResourceBundleImpl implements JoinableResourceBundle {
/** The logger */
private static final Logger LOGGER = LoggerFactory.getLogger(JoinableResourceBundleImpl.class);
/** The name of the bundle used in the configuration properties */
private String name;
/** The ID for this bundle. The URL, which will identify the bundle. */
private String id;
/** The inclusion pattern */
private InclusionPattern inclusionPattern;
/** The generator Registry */
private GeneratorRegistry generatorRegistry;
/** The bundle path mapping */
protected BundlePathMappingBuilder bundlePathMappingBuilder;
/** The bundle path mapping */
protected BundlePathMapping bundlePathMapping;
/** The flag indicating if the resource bundle is dirty */
private boolean dirty;
/** The bundle prefix */
private String bundlePrefix;
/** The URL prefix */
private String urlPrefix;
/** The IE conditional expression */
private String explorerConditionalExpression;
/** The alternate URL for the bundle */
private String alternateProductionURL;
/** The static URL to use in debug mode */
private String debugURL;
/** The prefix mapping for locale variant version */
private Map prefixMap;
/** The map of variants */
protected Map variants;
/** The list of variant keys */
protected List variantKeys;
/** The list of bundle dependencies */
protected List dependencies;
/** The file post processor */
private ResourceBundlePostProcessor unitaryPostProcessor;
/** The bundle post processor */
private ResourceBundlePostProcessor bundlePostProcessor;
/**
* Protected access constructor, which omits the mappings parameter.
*
* @param id
* the ID for this bundle.
* @param name
* The unique name for this bundle.
* @param bundlePrefix
* The bundle prefix
* @param fileExtension
* The File extensions for this bundle.
* @param inclusionPattern
* The Strategy for including this bundle.
* @param resourceReaderHandler
* ResourceHandler Used to access the files and folders.
* @param generatorRegistry
* The generator registry.
*/
public JoinableResourceBundleImpl(String id, String name, String bundlePrefix, String fileExtension,
InclusionPattern inclusionPattern, ResourceReaderHandler resourceReaderHandler,
GeneratorRegistry generatorRegistry) {
super();
this.inclusionPattern = inclusionPattern;
this.generatorRegistry = generatorRegistry;
if (generatorRegistry.isPathGenerated(id)) {
this.id = id;
} else {
this.id = PathNormalizer.asPath(id);
}
this.name = name;
if (bundlePrefix != null) {
this.bundlePrefix = PathNormalizer.asDirPath(bundlePrefix);
}
this.bundlePathMappingBuilder = createBundlePathMappingBuilder(fileExtension, resourceReaderHandler,
generatorRegistry);
this.bundlePathMapping = new BundlePathMapping(this);
prefixMap = new ConcurrentHashMap<>();
}
/**
* Constructor
*
* @param id
* the ID of this bundle
* @param name
* Unique name for this bundle.
* @param bundlePrefix
* The bundle prefix
* @param fileExtension
* File extensions for this bundle.
* @param inclusionPattern
* Strategy for including this bundle.
* @param pathMappings
* Set Strings representing the folders or files to include,
* possibly with wildcards.
* @param resourceReaderHandler
* Used to access the files and folders.
* @param generatorRegistry
* the generator registry
*/
public JoinableResourceBundleImpl(String id, String name, String bundlePrefix, String fileExtension,
InclusionPattern inclusionPattern, List pathMappings, ResourceReaderHandler resourceReaderHandler,
GeneratorRegistry generatorRegistry) {
this(id, name, bundlePrefix, fileExtension, inclusionPattern, resourceReaderHandler, generatorRegistry);
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Adding mapped files for bundle " + id);
}
this.bundlePathMappingBuilder = createBundlePathMappingBuilder(fileExtension, resourceReaderHandler,
generatorRegistry);
this.bundlePathMapping = bundlePathMappingBuilder.build(pathMappings);
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Added " + this.bundlePathMapping.getItemPathList().size() + " files and "
+ bundlePathMapping.getLicensesPathList().size() + " licenses for the bundle " + id);
}
}
/**
* Returns the bundle path mapping builder
*
* @param fileExtension
* the file extension
* @param resourceReaderHandler
* the resource reader handler
* @param generatorRegistry
* the generator registry
* @return the bundle path mapping builder
*/
protected BundlePathMappingBuilder createBundlePathMappingBuilder(String fileExtension,
ResourceReaderHandler resourceReaderHandler, GeneratorRegistry generatorRegistry) {
return new BundlePathMappingBuilder(this, fileExtension, generatorRegistry, resourceReaderHandler);
}
/*
* (non-Javadoc)
*
* @see net.jawr.web.resource.bundle.JoinableResourceBundle#getId()
*/
@Override
public String getId() {
return this.id;
}
/*
* (non-Javadoc)
*
* @see net.jawr.web.resource.bundle.JoinableResourceBundle#getName()
*/
@Override
public String getName() {
return name;
}
/*
* (non-Javadoc)
*
* @see
* net.jawr.web.resource.bundle.JoinableResourceBundle#getBundlePrefix()
*/
@Override
public String getBundlePrefix() {
return bundlePrefix;
}
/*
* (non-Javadoc)
*
* @see net.jawr.web.resource.bundle.JoinableResourceBundle#isComposite()
*/
@Override
public boolean isComposite() {
return false;
}
/*
* (non-Javadoc)
*
* @see net.jawr.web.resource.bundle.JoinableResourceBundle#
* getUnitaryPostProcessor ()
*/
@Override
public ResourceBundlePostProcessor getUnitaryPostProcessor() {
return unitaryPostProcessor;
}
/**
* Sets the unitary post processor
*
* @param unitaryPostProcessor
* the unitary post processor
*/
@Override
public void setUnitaryPostProcessor(ResourceBundlePostProcessor unitaryPostProcessor) {
this.unitaryPostProcessor = unitaryPostProcessor;
}
/*
* (non-Javadoc)
*
* @see net.jawr.web.resource.bundle.JoinableResourceBundle#
* getBundlePostProcessor ()
*/
@Override
public ResourceBundlePostProcessor getBundlePostProcessor() {
return bundlePostProcessor;
}
/**
* Sets the bundle post processor
*
* @param bundlePostProcessor
* the post processor to set
*/
@Override
public void setBundlePostProcessor(ResourceBundlePostProcessor bundlePostProcessor) {
this.bundlePostProcessor = bundlePostProcessor;
}
/*
* (non-Javadoc)
*
* @see net.jawr.web.resource.bundle.JoinableResourceBundle#
* getExplorerConditionalExpression()
*/
@Override
public String getExplorerConditionalExpression() {
return explorerConditionalExpression;
}
/**
* Set the conditional comment expression.
*
* @param explorerConditionalExpression
*/
public void setExplorerConditionalExpression(String explorerConditionalExpression) {
this.explorerConditionalExpression = explorerConditionalExpression;
}
/**
* Set the list of variants for variant resources
*
* @param variantSets
*/
@Override
public void setVariants(Map variantSets) {
if (variantSets != null) {
this.variants = new TreeMap<>(variantSets);
variantKeys = VariantUtils.getAllVariantKeys(this.variants);
}
}
/*
* (non-Javadoc)
*
* @see net.jawr.web.resource.bundle.JoinableResourceBundle#getVariants()
*/
@Override
public Map getVariants() {
return variants;
}
/*
* (non-Javadoc)
*
* @see
* net.jawr.web.resource.bundle.JoinableResourceBundle#getLocaleVariantKeys
* ()
*/
@Override
public List getVariantKeys() {
return variantKeys;
}
/*
* (non-Javadoc)
*
* @see net.jawr.web.resource.bundle.JoinableResourceBundle#
* getAlternateProductionURL ()
*/
@Override
public String getAlternateProductionURL() {
return this.alternateProductionURL;
}
/**
* Sets the alternate production URL
*
* @param alternateProductionURL
* the alternateProductionURL to set
*/
public void setAlternateProductionURL(String alternateProductionURL) {
this.alternateProductionURL = alternateProductionURL;
}
/*
* (non-Javadoc)
*
* @see net.jawr.web.resource.bundle.JoinableResourceBundle#getDebugURL()
*/
@Override
public String getDebugURL() {
return this.debugURL;
}
/**
* Sets the debug URL
*
* @param debugURL
* the debugURL to set
*/
public void setDebugURL(String debugURL) {
this.debugURL = debugURL;
}
/*
* (non-Javadoc)
*
* @see
* net.jawr.web.resource.bundle.JoinableResourceBundle#belongsTobundle(java
* .lang.String)
*/
@Override
public boolean belongsToBundle(String itemPath) {
boolean belongsToBundle = false;
for (BundlePath path : bundlePathMapping.getItemPathList()) {
if (path.getPath().equals(itemPath)) {
belongsToBundle = true;
break;
}
}
if (!belongsToBundle) {
for (BundlePath path : bundlePathMapping.getItemDebugPathList()) {
if (path.getPath().equals(itemPath)) {
belongsToBundle = true;
break;
}
}
}
return belongsToBundle;
}
/*
* (non-Javadoc)
*
* @see
* net.jawr.web.resource.bundle.JoinableResourceBundle#getInclusionPattern()
*/
@Override
public InclusionPattern getInclusionPattern() {
return this.inclusionPattern;
}
/*
* (non-Javadoc)
*
* @see
* net.jawr.web.resource.bundle.JoinableResourceBundle#setMappings(java.
* util.List)
*/
@Override
public void setMappings(List pathMappings) {
this.bundlePathMapping = this.bundlePathMappingBuilder.build(pathMappings);
}
/*
* (non-Javadoc)
*
* @see net.jawr.web.resource.bundle.JoinableResourceBundle#getMappings()
*/
@Override
public List getMappings() {
return this.bundlePathMapping.getPathMappings();
}
/*
* (non-Javadoc)
*
* @see
* net.jawr.web.resource.bundle.JoinableResourceBundle#getItemPathList()
*/
@Override
public List getItemPathList() {
return bundlePathMapping.getItemPathList();
}
/*
* (non-Javadoc)
*
* @see
* net.jawr.web.resource.bundle.JoinableResourceBundle#getItemDebugPathList
* ()
*/
@Override
public List getItemDebugPathList() {
return bundlePathMapping.getItemDebugPathList();
}
/*
* (non-Javadoc)
*
* @see
* net.jawr.web.resource.bundle.JoinableResourceBundle#getFilePathMappings
* ()
*/
@Override
public List getFilePathMappings() {
return bundlePathMapping.getFilePathMappings();
}
/*
* (non-Javadoc)
*
* @see net.jawr.web.resource.bundle.JoinableResourceBundle#
* getLinkedFilePathMappings()
*/
@Override
public List getLinkedFilePathMappings() {
return bundlePathMapping.getLinkedFilePathMappings();
}
/*
* (non-Javadoc)
*
* @see net.jawr.web.resource.bundle.JoinableResourceBundle#
* setLinkedFilePathMappings(java.util.List)
*/
@Override
public void setLinkedFilePathMappings(List mappings) {
this.bundlePathMapping.setLinkedFilePathMappings(mappings);
}
/*
* (non-Javadoc)
*
* @see
* net.jawr.web.resource.bundle.JoinableResourceBundle#getItemPathList(java
* .lang.String)
*/
@Override
public List getItemDebugPathList(Map variants) {
if (StringUtils.isNotEmpty(debugURL)) {
return bundlePathMapping.getItemDebugPathList();
}
return getItemPathList(bundlePathMapping.getItemDebugPathList(), variants);
}
/*
* (non-Javadoc)
*
* @see
* net.jawr.web.resource.bundle.JoinableResourceBundle#getItemPathList(java
* .lang.String)
*/
@Override
public List getItemPathList(Map variants) {
return getItemPathList(bundlePathMapping.getItemPathList(), variants);
}
/**
* Filters the bundlePath list given in parameter using the specified
* variants
*
* @param itemList
* the list of bundlePath
* @param variants
* the variants
* @return the filtered list of bundlePath
*/
private List getItemPathList(List itemList, Map variants) {
if (variants == null || variants.isEmpty()) {
return itemList;
}
List rets = new ArrayList<>();
for (BundlePath bundlePath : itemList) {
String path = bundlePath.getPath();
if (generatorRegistry.isPathGenerated(path)) {
Set variantTypes = generatorRegistry.getGeneratedResourceVariantTypes(path);
String variantKey = VariantUtils.getVariantKey(variants, variantTypes);
if (StringUtils.isNotEmpty(variantKey)) {
rets.add(new BundlePath(bundlePath.getBundlePrefix(),
VariantUtils.getVariantBundleName(path, variantKey, true)));
} else {
rets.add(bundlePath);
}
} else {
rets.add(bundlePath);
}
}
return rets;
}
/**
* Sets the bundle dependencies
*
* @param dependencies
* the bundle dependencies
*/
@Override
public void setDependencies(List dependencies) {
this.dependencies = dependencies;
}
/*
* (non-Javadoc)
*
* @see
* net.jawr.web.resource.bundle.JoinableResourceBundle#getDependencies()
*/
@Override
public List getDependencies() {
return dependencies;
}
/*
* (non-Javadoc)
*
* @see
* net.jawr.web.resource.bundle.JoinableResourceBundle#getLicensesPathList()
*/
@Override
public Set getLicensesPathList() {
return this.bundlePathMapping.getLicensesPathList();
}
/**
* Sets the licence path list
*
* @param licencePathList
* the list to set
*/
public void setLicensesPathList(Set licencePathList) {
this.bundlePathMapping.setLicensesPathList(licencePathList);
}
/*
* (non-Javadoc)
*
* @see
* net.jawr.web.resource.bundle.JoinableResourceBundle#getURLPrefix(java
* .util.Map)
*/
@Override
public String getURLPrefix(Map variants) {
if (null == this.urlPrefix)
throw new IllegalStateException("The bundleDataHashCode must be set before accessing the url prefix.");
if (variants != null && !variants.isEmpty()) {
String key = getAvailableVariant(variants);
if (StringUtils.isNotEmpty(key)) {
return prefixMap.get(key) + "." + key + "/";
}
}
return this.urlPrefix + "/";
}
/*
* (non-Javadoc)
*
* @see
* net.jawr.web.resource.bundle.JoinableResourceBundle#getBundleDataHashCode
* ()
*/
@Override
public String getBundleDataHashCode(String variantKey) {
if (StringUtils.isEmpty(variantKey)) {
return this.urlPrefix;
} else {
return (String) prefixMap.get(variantKey);
}
}
/*
* (non-Javadoc)
*
* @see
* net.jawr.web.resource.bundle.JoinableResourceBundle#setBundleDataHashCode
* (java.lang.String, java.lang.String)
*/
@Override
public void setBundleDataHashCode(String variantKey, String bundleDataHashCode) {
String prefix = bundleDataHashCode;
if (StringUtils.isEmpty(variantKey)) {
this.urlPrefix = prefix;
} else {
prefixMap.put(variantKey, prefix);
}
}
/**
* Resolves a registered path from a variant key.
*
* @param variantKey
* the requested variant key
* @return the variant key to use
*/
private String getAvailableVariant(Map curVariants) {
String variantKey = null;
if (variants != null) {
Map availableVariants = generatorRegistry.getAvailableVariantMap(variants, curVariants);
variantKey = VariantUtils.getVariantKey(availableVariants);
}
return variantKey;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return "JoinableResourceBundleImpl [id=" + id + ", name=" + name + "]";
}
/*
* (non-Javadoc)
*
* @see
* net.jawr.web.resource.bundle.JoinableResourceBundle#setDirty(boolean)
*/
@Override
public void setDirty(boolean dirty) {
this.dirty = dirty;
}
/*
* (non-Javadoc)
*
* @see net.jawr.web.resource.bundle.JoinableResourceBundle#isDirty()
*/
@Override
public boolean isDirty() {
return dirty;
}
/*
* (non-Javadoc)
*
* @see
* net.jawr.web.resource.bundle.JoinableResourceBundle#resetBundleMapping()
*/
@Override
public void resetBundleMapping() {
this.variants = null;
this.variantKeys = null;
this.bundlePathMapping = bundlePathMappingBuilder.build();
}
}