com.asual.lesscss.ResourcePackage Maven / Gradle / Ivy
/*
* 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.asual.lesscss;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.zip.DataFormatException;
import java.util.zip.Deflater;
import java.util.zip.Inflater;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* @author Rostislav Hristov
*/
public class ResourcePackage {
private final static Map cache = new ConcurrentHashMap();
private final static Log logger = LogFactory.getLog(ResourcePackage.class);
private final static List extensions = Arrays.asList("css", "less",
"js");
private static int NAME_FLAG = 1;
private static int VERSION_FLAG = 2;
private static int DEFLATE = 32;
private static String ENCODING = "UTF-8";
private static String NEW_LINE = "\n";
private static String SEPARATOR = "-";
private String[] resources;
private String version;
private String name;
private String extension;
public ResourcePackage(String[] resources) {
this.resources = resources;
}
public static ResourcePackage fromString(String source) {
if (!StringUtils.isEmpty(source)) {
try {
String key;
String path = null;
String extension = null;
int slashIndex = source.lastIndexOf("/");
int dotIndex = source.lastIndexOf(".");
if (dotIndex != -1 && slashIndex < dotIndex) {
extension = source.substring(dotIndex + 1);
path = source.substring(0, dotIndex);
} else {
path = source;
}
if (extension != null && !extensions.contains(extension)) {
return null;
}
String[] parts = path.replaceFirst("^/", "").split(SEPARATOR);
if (cache.containsValue(source)) {
key = getKeyFromValue(cache, source);
} else {
key = parts[parts.length - 1];
byte[] bytes = null;
try {
bytes = Base64.decodeBase64(key.getBytes(ENCODING));
bytes = inflate(bytes);
} catch (Exception e) {
}
key = new String(bytes, ENCODING);
}
String[] data = key.split(NEW_LINE);
ResourcePackage rp = new ResourcePackage(
(String[]) ArrayUtils.subarray(data, 1, data.length));
int mask = Integer.valueOf(data[0]);
if ((mask & NAME_FLAG) != 0) {
rp.setName(parts[0]);
}
if ((mask & VERSION_FLAG) != 0) {
rp.setVersion(parts[rp.getName() != null ? 1 : 0]);
}
rp.setExtension(extension);
return rp;
} catch (Exception e) {
}
}
return null;
}
public String toString() {
try {
if (extension != null && !extensions.contains(extension)) {
throw new Exception("Unsupported extension: " + extension);
}
int mask = 0;
if (name != null) {
mask = mask | NAME_FLAG;
}
if (version != null) {
mask = mask | VERSION_FLAG;
}
String key = mask + NEW_LINE
+ StringUtils.join(resources, NEW_LINE);
if (!cache.containsKey(key)) {
byte[] bytes = key.getBytes(ENCODING);
StringBuilder sb = new StringBuilder();
sb.append("/");
sb.append(name == null ? "" : name + SEPARATOR);
sb.append(version == null ? "" : version + SEPARATOR);
sb.append(Base64.encodeBase64URLSafeString(
bytes.length < DEFLATE ? bytes : deflate(bytes))
.replaceAll("-", "+"));
sb.append(extension == null ? "" : "." + extension);
cache.put(key, sb.toString());
}
return cache.get(key);
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
return null;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getExtension() {
return extension;
}
public void setExtension(String extension) {
this.extension = extension;
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
public String[] getResources() {
return resources;
}
public static K getKeyFromValue(Map m, V value) {
for (K o : m.keySet()) {
if (m.get(o).equals(value)) {
return o;
}
}
return null;
}
private static byte[] deflate(byte[] input) throws IOException {
Deflater deflater = new Deflater();
deflater.setLevel(Deflater.BEST_COMPRESSION);
deflater.setInput(input);
deflater.finish();
ByteArrayOutputStream baos = new ByteArrayOutputStream(input.length);
byte[] buf = new byte[1024];
while (!deflater.finished()) {
int count = deflater.deflate(buf);
baos.write(buf, 0, count);
}
baos.close();
return baos.toByteArray();
}
private static byte[] inflate(byte[] output) throws DataFormatException,
IOException {
Inflater inflater = new Inflater();
inflater.setInput(output);
ByteArrayOutputStream baos = new ByteArrayOutputStream(output.length);
byte[] buf = new byte[1024];
while (!inflater.finished()) {
int count = inflater.inflate(buf);
baos.write(buf, 0, count);
}
baos.close();
return baos.toByteArray();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy