Skip to content

Commit

Permalink
remove Utils#toByteArray() in favor of InputStream#readAllBytes()
Browse files Browse the repository at this point in the history
  • Loading branch information
BalusC committed May 12, 2024
1 parent a94e2bc commit 03f34d4
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 112 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
package org.omnifaces.resourcehandler;

import static org.omnifaces.util.Faces.getMimeType;
import static org.omnifaces.util.Utils.toByteArray;

import java.io.ByteArrayInputStream;
import java.io.IOException;
Expand All @@ -22,7 +21,6 @@
import jakarta.faces.application.Resource;
import jakarta.faces.context.FacesContext;

import org.omnifaces.util.cache.Cache;
import org.omnifaces.util.cache.CacheFactory;

/**
Expand Down Expand Up @@ -55,7 +53,7 @@ public class CombinedResource extends DynamicResource {
*/
public CombinedResource(String resourceName, Integer cacheTTL) {
super(resourceName, CombinedResourceHandler.LIBRARY_NAME, getMimeType(resourceName));
String[] resourcePathParts = resourceName.split("\\.", 2)[0].split("/");
var resourcePathParts = resourceName.split("\\.", 2)[0].split("/");
resourceId = resourcePathParts[resourcePathParts.length - 1];
info = CombinedResourceInfo.get(resourceId);
this.cacheTTL = cacheTTL;
Expand All @@ -65,7 +63,7 @@ public CombinedResource(String resourceName, Integer cacheTTL) {

@Override
public long getLastModified() {
return (info != null) ? info.getLastModified() : super.getLastModified();
return info != null ? info.getLastModified() : super.getLastModified();
}

@Override
Expand All @@ -87,15 +85,17 @@ public InputStream getInputStream() throws IOException {
* Returns the cached input stream, or if there is none, then create one.
*/
private InputStream getInputStreamFromCache() throws IOException {
Cache combinedResourceCache = CacheFactory.getCache(FacesContext.getCurrentInstance(), CACHE_SCOPE);
var combinedResourceCache = CacheFactory.getCache(FacesContext.getCurrentInstance(), CACHE_SCOPE);
byte[] cachedCombinedResource;

synchronized (CombinedResourceHandler.class) {
cachedCombinedResource = (byte[]) combinedResourceCache.getObject(resourceId);
}

if (cachedCombinedResource == null) {
cachedCombinedResource = toByteArray(new CombinedResourceInputStream(info.getResources()));
try (var combinedResourceInputStream = new CombinedResourceInputStream(info.getResources())) {
cachedCombinedResource = combinedResourceInputStream.readAllBytes();
}

synchronized (CombinedResourceHandler.class) {
if (combinedResourceCache.getObject(resourceId) == null) {
Expand Down
56 changes: 27 additions & 29 deletions src/main/java/org/omnifaces/resourcehandler/GraphicResource.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
import static org.omnifaces.util.Utils.isOneAnnotationPresent;
import static org.omnifaces.util.Utils.isOneInstanceOf;
import static org.omnifaces.util.Utils.isOneOf;
import static org.omnifaces.util.Utils.toByteArray;

import java.io.ByteArrayInputStream;
import java.io.IOException;
Expand All @@ -49,7 +48,6 @@
import jakarta.el.ValueExpression;
import jakarta.enterprise.inject.Any;
import jakarta.enterprise.inject.spi.Bean;
import jakarta.enterprise.inject.spi.BeanManager;
import jakarta.enterprise.util.AnnotationLiteral;
import jakarta.faces.FacesException;
import jakarta.faces.application.Resource;
Expand Down Expand Up @@ -78,7 +76,7 @@ public class GraphicResource extends DynamicResource {
private static final String DEFAULT_CONTENT_TYPE = "image";
private static final Map<String, String> CONTENT_TYPES_BY_BASE64_HEADER = createContentTypesByBase64Header();
private static final Map<String, MethodReference> ALLOWED_METHODS = new ConcurrentHashMap<>();
private static final String[] EMPTY_PARAMS = new String[0];
private static final String[] EMPTY_PARAMS = {};

@SuppressWarnings({ "unchecked" })
private static final Class<? extends Annotation>[] REQUIRED_ANNOTATION_TYPES = new Class[] {
Expand All @@ -92,7 +90,7 @@ public class GraphicResource extends DynamicResource {
byte[].class
};

private static final AnnotationLiteral<Any> ANY = new AnnotationLiteral<Any>() {
private static final AnnotationLiteral<Any> ANY = new AnnotationLiteral<>() {
private static final long serialVersionUID = 1L;
};

Expand Down Expand Up @@ -166,7 +164,7 @@ else if (lastModified instanceof Date) {
setLastModified(((Date) lastModified).getTime());
}
else if (isNumber(String.valueOf(lastModified))) {
setLastModified(Long.valueOf(lastModified.toString()));
setLastModified(Long.parseLong(lastModified.toString()));
}
else if (lastModified != null) {
throw new IllegalArgumentException(format(ERROR_INVALID_LASTMODIFIED, lastModified));
Expand All @@ -188,15 +186,15 @@ else if (lastModified != null) {
* <code>&lt;mime-mapping&gt;</code> in <code>web.xml</code>).
*/
public static GraphicResource create(FacesContext context, ValueExpression value, String type, Object lastModified) {
MethodReference methodReference = ExpressionInspector.getMethodReference(context.getELContext(), value);
Method beanMethod = methodReference.getMethod();
var methodReference = ExpressionInspector.getMethodReference(context.getELContext(), value);
var beanMethod = methodReference.getMethod();

if (beanMethod == null) {
throw new IllegalArgumentException(format(ERROR_UNKNOWN_METHOD, value.getExpressionString()));
}

Class<?> beanClass = methodReference.getBase().getClass();
String name = getResourceBaseName(beanClass, beanMethod);
var name = getResourceBaseName(beanClass, beanMethod);

if (!ALLOWED_METHODS.containsKey(name)) { // No need to validate everytime when already known.
if (!isOneAnnotationPresent(beanClass, REQUIRED_ANNOTATION_TYPES)) {
Expand All @@ -210,8 +208,8 @@ public static GraphicResource create(FacesContext context, ValueExpression value
ALLOWED_METHODS.put(name, new MethodReference(methodReference.getBase(), beanMethod));
}

Object[] params = methodReference.getActualParameters();
String[] convertedParams = convertToStrings(context, params, beanMethod.getParameterTypes());
var params = methodReference.getActualParameters();
var convertedParams = convertToStrings(context, params, beanMethod.getParameterTypes());
return new GraphicResource(name + (isEmpty(type) ? "" : "." + type), convertedParams, lastModified);
}

Expand All @@ -224,14 +222,14 @@ public String getRequestPath() {
return "data:" + getContentType() + ";base64," + base64;
}
else {
String queryString = isEmpty(params) ? "" : ("&" + toQueryString(singletonMap("p", asList(params))));
var queryString = isEmpty(params) ? "" : "&" + toQueryString(singletonMap("p", asList(params)));
return super.getRequestPath() + queryString;
}
}

@Override
public InputStream getInputStream() throws IOException {
MethodReference methodReference = ALLOWED_METHODS.get(getResourceName().split("\\.", 2)[0]);
var methodReference = ALLOWED_METHODS.get(getResourceName().split("\\.", 2)[0]);

Method method;
Object[] convertedParams;
Expand Down Expand Up @@ -289,7 +287,7 @@ private static Map<String, String> createContentTypesByBase64Header() {
* @throws IllegalArgumentException When bean method is missing.
*/
public static void registerGraphicImageBeans() {
BeanManager beanManager = getManager();
var beanManager = getManager();

for (Bean<?> bean : beanManager.getBeans(Object.class, ANY)) {
Class<?> beanClass = bean.getBeanClass();
Expand All @@ -299,12 +297,12 @@ public static void registerGraphicImageBeans() {
}

Object instance = getReference(beanManager, bean);
boolean registered = false;
var registered = false;

for (Method method : beanClass.getMethods()) {
if (isPublic(method.getModifiers()) && isOneInstanceOf(method.getReturnType(), REQUIRED_RETURN_TYPES)) {
String resourceBaseName = getResourceBaseName(beanClass, method);
MethodReference methodReference = new MethodReference(instance, method);
var resourceBaseName = getResourceBaseName(beanClass, method);
var methodReference = new MethodReference(instance, method);
ALLOWED_METHODS.put(resourceBaseName, methodReference);
registered = true;
}
Expand Down Expand Up @@ -332,7 +330,7 @@ private static String getContentType(String resourceName) {
return DEFAULT_CONTENT_TYPE;
}

String contentType = getExternalContext().getMimeType(resourceName);
var contentType = getExternalContext().getMimeType(resourceName);

if (contentType == null) {
throw new IllegalArgumentException(format(ERROR_INVALID_TYPE, resourceName.split("\\.", 2)[1]));
Expand Down Expand Up @@ -361,16 +359,16 @@ private static String guessContentType(String base64) {
private static String convertToBase64(Object content) {
byte[] bytes;

if (content instanceof InputStream) {
if (content instanceof InputStream inputStream) {
try {
bytes = toByteArray((InputStream) content);
bytes = inputStream.readAllBytes();
}
catch (IOException e) {
throw new FacesException(e);
}
}
else if (content instanceof byte[]) {
bytes = (byte[]) content;
else if (content instanceof byte[] byteArray) {
bytes = byteArray;
}
else {
throw new IllegalArgumentException(format(ERROR_INVALID_RETURNTYPE, content));
Expand All @@ -385,13 +383,13 @@ else if (content instanceof byte[]) {
*/
private static String[] convertToStrings(FacesContext context, Object[] values, Class<?>[] types) {
validateParamLength(values, types);
String[] strings = new String[values.length];
var strings = new String[values.length];
UIComponent dummyComponent = new UIOutput();

for (int i = 0; i < values.length; i++) {
Object value = values[i];
for (var i = 0; i < values.length; i++) {
var value = values[i];
Converter<Object> converter = createConverter(context, types[i]);
strings[i] = (converter != null)
strings[i] = converter != null
? converter.getAsString(context, dummyComponent, value)
: coalesce(value, "").toString();
}
Expand All @@ -405,13 +403,13 @@ private static String[] convertToStrings(FacesContext context, Object[] values,
*/
private static Object[] convertToObjects(FacesContext context, String[] values, Class<?>[] types) {
validateParamLength(values, types);
Object[] objects = new Object[values.length];
var objects = new Object[values.length];
UIComponent dummyComponent = new UIOutput();

for (int i = 0; i < values.length; i++) {
String value = isEmpty(values[i]) ? null : values[i];
for (var i = 0; i < values.length; i++) {
var value = isEmpty(values[i]) ? null : values[i];
Converter<Object> converter = createConverter(context, types[i]);
objects[i] = (converter != null)
objects[i] = converter != null
? converter.getAsObject(context, dummyComponent, value)
: value;
}
Expand Down
32 changes: 13 additions & 19 deletions src/main/java/org/omnifaces/resourcehandler/ResourceIdentifier.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@
import static java.lang.String.format;
import static java.util.logging.Level.WARNING;
import static org.omnifaces.util.FacesLocal.createResource;
import static org.omnifaces.util.Utils.toByteArray;

import java.security.MessageDigest;
import java.util.Base64;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Logger;

Expand Down Expand Up @@ -56,16 +56,16 @@ public class ResourceIdentifier {
* @param resourceIdentifier The standard Faces resource identifier.
*/
public ResourceIdentifier(String resourceIdentifier) {
String[] parts = resourceIdentifier.split(":");
setLibraryAndName((parts.length > 1) ? parts[0] : null, parts[parts.length - 1]);
var parts = resourceIdentifier.split(":");
setLibraryAndName(parts.length > 1 ? parts[0] : null, parts[parts.length - 1]);
}

/**
* Create a new instance based on library and name attributes of the given component resource.
* @param componentResource The component resource.
*/
public ResourceIdentifier(UIComponent componentResource) {
Map<String, Object> attributes = componentResource.getAttributes();
var attributes = componentResource.getAttributes();
setLibraryAndName((String) attributes.get("library"), (String) attributes.get("name"));
}

Expand All @@ -89,7 +89,7 @@ public ResourceIdentifier(Resource resource) {

private void setLibraryAndName(String library, String name) {
this.library = library;
this.name = (name != null) ? name.split("[?#;]", 2)[0] : null; // Split gets rid of query string and path fragment.
this.name = name != null ? name.split("[?#;]", 2)[0] : null; // Split gets rid of query string and path fragment.
}

// Getters --------------------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -134,11 +134,8 @@ public boolean equals(Object object) {
}

// Property checks.
ResourceIdentifier other = (ResourceIdentifier) object;
if (library == null ? other.library != null : !library.equals(other.library)) {
return false;
}
if (name == null ? other.name != null : !name.equals(other.name)) {
var other = (ResourceIdentifier) object;
if ((library == null ? other.library != null : !library.equals(other.library)) || (name == null ? other.name != null : !name.equals(other.name))) {
return false;
}

Expand All @@ -148,11 +145,7 @@ public boolean equals(Object object) {

@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((library == null) ? 0 : library.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
return Objects.hash(library, name);
}

/**
Expand All @@ -161,16 +154,17 @@ public int hashCode() {
*/
@Override
public String toString() {
return (library != null ? (library + ":") : "") + name;
return (library != null ? library + ":" : "") + name;
}

// Helpers --------------------------------------------------------------------------------------------------------

private static String computeIntegrity(FacesContext context, ResourceIdentifier id) {
try {
byte[] content = toByteArray(createResource(context, id).getInputStream());
byte[] sha384 = MessageDigest.getInstance("SHA-384").digest(content);
return "sha384-" + Base64.getEncoder().encodeToString(sha384);
try (var inputStream = createResource(context, id).getInputStream()) {
var sha384 = MessageDigest.getInstance("SHA-384").digest(inputStream.readAllBytes());
return "sha384-" + Base64.getEncoder().encodeToString(sha384);
}
}
catch (Exception e) {
logger.log(WARNING, format(WARNING_CANNOT_COMPUTE_INTEGRITY, id), e);
Expand Down

0 comments on commit 03f34d4

Please sign in to comment.