org.wisdom.content.bodyparsers.BodyParserForm Maven / Gradle / Ivy
/*
* #%L
* Wisdom-Framework
* %%
* Copyright (C) 2013 - 2014 Wisdom Framework
* %%
* 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.
* #L%
*/
package org.wisdom.content.bodyparsers;
import com.google.common.collect.ImmutableList;
import org.apache.felix.ipojo.annotations.Component;
import org.apache.felix.ipojo.annotations.Instantiate;
import org.apache.felix.ipojo.annotations.Provides;
import org.apache.felix.ipojo.annotations.Requires;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.wisdom.api.content.BodyParser;
import org.wisdom.api.content.ParameterFactories;
import org.wisdom.api.http.Context;
import org.wisdom.api.http.FileItem;
import org.wisdom.api.http.MimeTypes;
import org.wisdom.content.converters.ReflectionHelper;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
@Component
@Provides
@Instantiate
public class BodyParserForm implements BodyParser {
private static final Logger LOGGER = LoggerFactory.getLogger(BodyParser.class);
private static final String ERROR_KEY = "Error parsing incoming form data for key ";
private static final String ERROR_AND = " and value ";
@Requires
ParameterFactories converters;
/**
* Creates a object of class T from a form sent in the request.
*
* @param context The context
* @param classOfT The class we expect
* @param genericType the generic type (ignored)
* @param the class ot the object to build
* @return the object, {@code null} if the object cannot be built.
*/
@Override
public T invoke(Context context, Class classOfT, Type genericType) {
T t;
try {
t = classOfT.newInstance();
} catch (Exception e) {
LOGGER.error("Failed to create a new instance of {}", classOfT, e);
return null;
}
Map properties = ReflectionHelper.getProperties(classOfT, genericType);
// 1) Query parameters
for (Entry> ent : context.parameters().entrySet()) {
try {
ReflectionHelper.Property property = properties.get(ent.getKey());
if (property != null) {
Object value = converters.convertValues(ent.getValue(), property.getClassOfProperty(),
property.getGenericTypeOfProperty(),
null);
property.set(t, value);
}
} catch (Exception e) {
LOGGER.warn(ERROR_KEY + ent.getKey() + ERROR_AND + ent.getValue(), e);
}
}
// 2) Path parameters
final Map fromPath = context.route().getPathParametersEncoded(context.request().uri());
for (Entry ent : fromPath
.entrySet()) {
try {
ReflectionHelper.Property property = properties.get(ent.getKey());
if (property != null) {
Object value = converters.convertValue(ent.getValue(), property.getClassOfProperty(),
property.getGenericTypeOfProperty(), null);
property.set(t, value);
}
} catch (Exception e) {
// Path parameter are rarely used in form, so, set the log level to 'debug'.
LOGGER.debug(ERROR_KEY + ent.getKey() + ERROR_AND + ent.getValue(), e);
}
}
// 3) Forms.
if (context.form() == null || context.form().isEmpty()) {
return t;
}
for (Entry> ent : context.form().entrySet()) {
try {
ReflectionHelper.Property property = properties.get(ent.getKey());
if (property != null) {
Object value = converters.convertValues(ent.getValue(), property.getClassOfProperty(),
property.getGenericTypeOfProperty(), null);
property.set(t, value);
}
} catch (Exception e) {
LOGGER.warn(ERROR_KEY + ent.getKey() + ERROR_AND + ent.getValue(), e);
}
}
// 4) File Items.
if (context.files() == null || context.files().isEmpty()) {
return t;
}
for (FileItem item : context.files()) {
try {
ReflectionHelper.Property property = properties.get(item.field());
if (property != null) {
if (InputStream.class.isAssignableFrom(property.getClassOfProperty())) {
property.set(t, item.stream());
} else if (FileItem.class.isAssignableFrom(property.getClassOfProperty())) {
property.set(t, item);
} else if (property.getClassOfProperty().isArray()
&& property.getClassOfProperty().getComponentType().equals(Byte.TYPE)) {
property.set(t, item.bytes());
}
}
} catch (Exception e) {
LOGGER.warn(ERROR_KEY + item.field() + ERROR_AND + item, e);
}
}
return t;
}
/**
* Creates a object of class T from a form sent in the request.
*
* @param context The context
* @param classOfT The class we expect
* @param the class ot the object to build
* @return the object, {@code null} if the object cannot be built.
*/
@Override
public T invoke(Context context, Class classOfT) {
return invoke(context, classOfT, null);
}
/**
* Unsupported operation.
*
* @param bytes the content
* @param classOfT The class we expect
* @param the class
* @return nothing as this method is not supported
*/
@Override
public T invoke(byte[] bytes, Class classOfT) {
throw new UnsupportedOperationException("Cannot bind a raw byte[] to a form object");
}
/**
* @return a list containing {@code application/x-www-form-urlencoded} and {@code multipart/form}.
*/
public List getContentTypes() {
return ImmutableList.of(MimeTypes.FORM, MimeTypes.MULTIPART);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy