Skip to content

Commit

Permalink
Made it possible to inject request parameters in a model and to adapt…
Browse files Browse the repository at this point in the history
… from a request immediatly instead of using request.getResource(). This way you could adapt your request in a servlet to a model with request parameters as fields.
  • Loading branch information
royteeuwen committed Oct 13, 2017
1 parent 7e98ba4 commit 6ba0416
Show file tree
Hide file tree
Showing 6 changed files with 155 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Service;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.adapter.AdapterFactory;
import org.apache.sling.api.resource.Resource;
import org.osgi.framework.Bundle;
Expand Down Expand Up @@ -145,7 +146,7 @@ private ServiceRegistration createAdapterFactory(Collection<Class<?>> classes, S
SliceAdapterFactory factory = new SliceAdapterFactory(name);

Dictionary<String, Object> properties = new Hashtable<String, Object>();
properties.put(AdapterFactory.ADAPTABLE_CLASSES, new String[] { Resource.class.getName() });
properties.put(AdapterFactory.ADAPTABLE_CLASSES, new String[] { Resource.class.getName(), SlingHttpServletRequest.class.getName() });
properties.put(AdapterFactory.ADAPTER_CLASSES, adapterClassNames);
return bundleContext.registerService(AdapterFactory.class.getName(), factory, properties);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

package com.cognifide.slice.core.internal.adapter;

import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.adapter.AdapterFactory;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
Expand Down Expand Up @@ -47,10 +48,16 @@ public SliceAdapterFactory(String injectorName) {

@Override
public <AdapterType> AdapterType getAdapter(Object adaptable, Class<AdapterType> type) {
if (!(adaptable instanceof Resource)) {
if (!((adaptable instanceof Resource) || (adaptable instanceof SlingHttpServletRequest))) {
return null;
}
Resource resource = (Resource) adaptable;

Resource resource;
if(adaptable instanceof Resource) {
resource = (Resource) adaptable;
} else {
resource = ((SlingHttpServletRequest) adaptable).getResource();
}

InjectorWithContext injector = getInjector(resource);
if (injector != null) {
Expand All @@ -67,7 +74,7 @@ public <AdapterType> AdapterType getAdapter(Object adaptable, Class<AdapterType>
}
}

private InjectorWithContext getInjector(Resource resource) {
private InjectorWithContext getInjector(Resource resource) {
ResourceResolver resourceResolver = resource.getResourceResolver();
InjectorsRepository repository = resourceResolver.adaptTo(InjectorsRepository.class);
if (repository == null) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*-
* #%L
* Slice - Mapper API
* %%
* Copyright (C) 2012 Cognifide Limited
* %%
* 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 com.cognifide.slice.mapper.annotation;

import java.lang.annotation.*;

/**
* Indicates that a given field should be mapped from a request parameter . The
* name of the request parameter is indicated by the name of the field or value of {@link RequestParameter} (if
* specified). Only a type of string is allowed
* Example:
*
* <pre>
* {@literal @}SliceResource
* public class ExampleModel {
*
* {@literal @}RequestParameter
* private String myParameter;
*
* {@literal @}RequestParameter("second-parameter")
* private String secondParameter;
* }
* </pre>
*
* @author roy.teeuwen
*
*/
@Documented
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RequestParameter {

/**
* Custom request parameter name. If empty, property name is read from field's name.
*
* @return value
*/
String value() default "";
}
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ public final class MapperBuilder {
@Inject
private RequestAttributeProcessor requestAttributeProcessor;

@Inject
private RequestParameterProcessor requestParameterProcessor;

@Inject
private CustomProcessorsCollector customProcessorsCollector;

Expand Down Expand Up @@ -118,6 +121,7 @@ public MapperBuilder addSliceProcessors() {
processors.add(sliceResourceFieldProcessor); // @SliceResource
processors.add(childrenFieldProcessor); // child models @Children
processors.add(requestAttributeProcessor); // @RequestAttribute
processors.add(requestParameterProcessor); // @RequestParameter
processors.add(new ListFieldProcessor()); // Subclasses of Collection<?> and arrays
processors.add(new BooleanFieldProcessor()); // booleans
processors.add(new EnumFieldProcessor()); // enums
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*-
* #%L
* Slice - Mapper
* %%
* Copyright (C) 2012 Cognifide Limited
* %%
* 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 com.cognifide.slice.mapper.impl.processor;

import com.cognifide.slice.mapper.annotation.RequestParameter;
import com.cognifide.slice.mapper.api.processor.FieldProcessor;
import com.google.inject.Inject;
import org.apache.commons.lang.StringUtils;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ValueMap;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

public class RequestParameterProcessor implements FieldProcessor {

@Inject
private SlingHttpServletRequest slingRequest;

@Override
public boolean accepts(final Resource resource, final Field field) {
Class<?> fieldType = field.getType();
return (Collection.class.isAssignableFrom(fieldType) || fieldType.equals(String.class)) && field.isAnnotationPresent(RequestParameter.class);
}

@Override
public Object mapResourceToField(Resource resource, ValueMap valueMap, Field field, String propertyName) {
String parameterName = getParameterName(field);
Class<?> fieldType = field.getType();
if (Collection.class.isAssignableFrom(fieldType)) {
org.apache.sling.api.request.RequestParameter[] parameters = slingRequest.getRequestParameters(parameterName);
if (parameters != null) {
return getParameterValues(parameters);
}
} else {
org.apache.sling.api.request.RequestParameter parameter = slingRequest.getRequestParameter(parameterName);
if (parameter != null) {
return parameter.getString();
}
}
return null;
}

private List<String> getParameterValues(org.apache.sling.api.request.RequestParameter[] parameters) {
List<String> result = new ArrayList<String>();
for (org.apache.sling.api.request.RequestParameter parameter : parameters) {
result.add(parameter.getString());
}
return result;
}

private String getParameterName(Field field) {
final RequestParameter annotation = field.getAnnotation(RequestParameter.class);
if ((annotation != null) && StringUtils.isNotBlank(annotation.value())) {
return annotation.value();
}
return field.getName();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,21 @@

import com.cognifide.slice.mapper.annotation.JcrProperty;
import com.cognifide.slice.mapper.annotation.RequestAttribute;
import com.cognifide.slice.mapper.annotation.RequestParameter;
import com.cognifide.slice.mapper.strategy.MapperStrategy;

/**
* AnnotatedFieldMapperStrategy defines a strategy where only fields annotated by
* {@link JcrProperty}, {@link RequestAttribute} are mapped.
* {@link JcrProperty}, {@link RequestAttribute} or {@link RequestParameter} are mapped.
*
*/
public class AnnotatedFieldMapperStrategy implements MapperStrategy {

@Override
public boolean shouldFieldBeMapped(Field field) {
return (field.isAnnotationPresent(JcrProperty.class)
|| field.isAnnotationPresent(RequestAttribute.class));
|| field.isAnnotationPresent(RequestAttribute.class)
|| field.isAnnotationPresent(RequestParameter.class));
}

}

0 comments on commit 6ba0416

Please sign in to comment.