Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

First version of @Convert(with=SomeConverter.class)

  • Loading branch information...
commit 3c60b6d3b300798567dda629d50db653194f92e2 1 parent cc0262a
@chkal chkal authored
View
32 config-annotations/src/main/java/org/ocpsoft/rewrite/annotation/Convert.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2011 <a href="mailto:lincolnbaxter@gmail.com">Lincoln Baxter, III</a>
+ *
+ * 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 org.ocpsoft.rewrite.annotation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Inherited
+@Documented
+@Target(ElementType.FIELD)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Convert
+{
+ Class<?> with();
+}
View
116 config-annotations/src/main/java/org/ocpsoft/rewrite/annotation/handler/ConvertHandler.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2011 <a href="mailto:lincolnbaxter@gmail.com">Lincoln Baxter, III</a>
+ *
+ * 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 org.ocpsoft.rewrite.annotation.handler;
+
+import java.lang.reflect.Field;
+import java.util.Iterator;
+
+import org.ocpsoft.common.services.ServiceLoader;
+import org.ocpsoft.common.util.Assert;
+import org.ocpsoft.logging.Logger;
+import org.ocpsoft.rewrite.annotation.Convert;
+import org.ocpsoft.rewrite.annotation.api.FieldContext;
+import org.ocpsoft.rewrite.annotation.api.HandlerChain;
+import org.ocpsoft.rewrite.annotation.spi.ConverterProvider;
+import org.ocpsoft.rewrite.annotation.spi.FieldAnnotationHandler;
+import org.ocpsoft.rewrite.bind.BindingBuilder;
+import org.ocpsoft.rewrite.bind.Converter;
+import org.ocpsoft.rewrite.context.EvaluationContext;
+import org.ocpsoft.rewrite.event.Rewrite;
+
+/**
+ * Handler for {@link Convert}.
+ *
+ * @author Christian Kaltepoth
+ */
+public class ConvertHandler extends FieldAnnotationHandler<Convert>
+{
+ private final Logger log = Logger.getLogger(ConvertHandler.class);
+
+ @Override
+ public Class<Convert> handles()
+ {
+ return Convert.class;
+ }
+
+ @Override
+ public int priority()
+ {
+ return HandlerWeights.WEIGHT_TYPE_ENRICHING;
+ }
+
+ @Override
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ public void process(FieldContext context, Convert annotation, HandlerChain chain)
+ {
+ Field field = context.getJavaField();
+
+ // locate the binding previously created by @ParameterBinding
+ BindingBuilder bindingBuilder = (BindingBuilder) context.get(BindingBuilder.class);
+ Assert.notNull(bindingBuilder, "No binding found for field: " + field);
+
+ // add the converter
+ Class<?> converterType = annotation.with();
+ LazyConverterAdapter converter = new LazyConverterAdapter(converterType);
+ bindingBuilder.convertedBy(converter);
+
+ // some logging
+ if (log.isTraceEnabled()) {
+ log.trace("Attached converter adapeter for [{}] to field [{}] of class [{}]", new Object[] {
+ converterType.getSimpleName(), field.getName(), field.getDeclaringClass().getName()
+ });
+ }
+
+ // continue with the chain
+ chain.proceed();
+
+ }
+
+ /**
+ * This class uses the {@link ConverterProvider} SPI to lazily obtain the {@link Converter} for a given {@link Class} instance.
+ */
+ private static class LazyConverterAdapter implements Converter<Object>
+ {
+
+ private final Class<?> converterClass;
+
+ public LazyConverterAdapter(Class<?> clazz)
+ {
+ this.converterClass = clazz;
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public Object convert(Rewrite event, EvaluationContext context, Object value)
+ {
+
+ Converter<?> converter = null;
+
+ // let one of the SPI implementations build the converter
+ Iterator<ConverterProvider> providers = ServiceLoader.load(ConverterProvider.class).iterator();
+ while (providers.hasNext()) {
+ converter = providers.next().getByType(converterClass);
+ if (converter != null) {
+ break;
+ }
+ }
+ Assert.notNull(converter, "Could not build converter for type: " + converterClass.getName());
+
+ return converter.convert(event, context, value);
+
+ }
+ }
+}
View
34 config-annotations/src/main/java/org/ocpsoft/rewrite/annotation/spi/ConverterProvider.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2011 <a href="mailto:lincolnbaxter@gmail.com">Lincoln Baxter, III</a>
+ *
+ * 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 org.ocpsoft.rewrite.annotation.spi;
+
+import org.ocpsoft.rewrite.bind.Converter;
+
+/**
+ * SPI for providing integration with other conversion frameworks. Implementations should be able to build an Rewrite
+ * {@link Converter} from any kind of 3rd party class.
+ *
+ * @author Christian Kaltepoth
+ */
+public interface ConverterProvider
+{
+
+ /**
+ * Create a Rewrite {@link Converter} from the given converter class. Which types are supported is up to the
+ * implementation class. A JSF implementation would for example support JSF converters.
+ */
+ Converter<?> getByType(Class<?> converterClass);
+}
View
51 config-annotations/src/main/java/org/ocpsoft/rewrite/annotation/spi/DefaultConverterProvider.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2011 <a href="mailto:lincolnbaxter@gmail.com">Lincoln Baxter, III</a>
+ *
+ * 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 org.ocpsoft.rewrite.annotation.spi;
+
+import org.ocpsoft.rewrite.bind.Converter;
+
+/**
+ * Default implementation of {@link ConverterProvider} that builds {@link Converter} instances by creating an instance
+ * of the supplied class using the default constructor.
+ *
+ * @author Christian Kaltepoth
+ */
+public class DefaultConverterProvider implements ConverterProvider
+{
+
+ @Override
+ public Converter<?> getByType(Class<?> converterClass)
+ {
+
+ if (Converter.class.isAssignableFrom(converterClass)) {
+
+ try {
+ return (Converter<?>) converterClass.newInstance();
+ }
+ catch (InstantiationException e) {
+ throw new IllegalArgumentException(e);
+ }
+ catch (IllegalAccessException e) {
+ throw new IllegalArgumentException(e);
+ }
+
+ }
+
+ return null;
+
+ }
+
+}
View
1  ...ig-annotations/src/main/resources/META-INF/services/org.ocpsoft.rewrite.annotation.spi.AnnotationHandler
@@ -8,3 +8,4 @@ org.ocpsoft.rewrite.annotation.handler.RolesRequiredHandler
org.ocpsoft.rewrite.annotation.handler.ParameterBindingHandler
org.ocpsoft.rewrite.annotation.handler.MatchesHandler
org.ocpsoft.rewrite.annotation.handler.ForwardToHandler
+org.ocpsoft.rewrite.annotation.handler.ConvertHandler
View
1  ...ig-annotations/src/main/resources/META-INF/services/org.ocpsoft.rewrite.annotation.spi.ConverterProvider
@@ -0,0 +1 @@
+org.ocpsoft.rewrite.annotation.spi.DefaultConverterProvider
View
30 config-annotations/src/test/java/org/ocpsoft/rewrite/annotation/convert/CustomConverterBean.java
@@ -0,0 +1,30 @@
+package org.ocpsoft.rewrite.annotation.convert;
+
+import javax.enterprise.context.RequestScoped;
+import javax.inject.Named;
+
+import org.ocpsoft.rewrite.annotation.Convert;
+import org.ocpsoft.rewrite.annotation.Join;
+import org.ocpsoft.rewrite.annotation.ParameterBinding;
+
+@Named
+@RequestScoped
+@Join(path = "/convert/{value}/", to = "/convert.jsp")
+public class CustomConverterBean
+{
+
+ @ParameterBinding
+ @Convert(with = LowercaseConverter.class)
+ private String value;
+
+ public String getValue()
+ {
+ return value;
+ }
+
+ public void setValue(String value)
+ {
+ this.value = value;
+ }
+
+}
View
42 config-annotations/src/test/java/org/ocpsoft/rewrite/annotation/convert/CustomConverterTest.java
@@ -0,0 +1,42 @@
+package org.ocpsoft.rewrite.annotation.convert;
+
+import static junit.framework.Assert.assertTrue;
+import static org.junit.Assert.assertEquals;
+
+import org.apache.http.client.methods.HttpGet;
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.arquillian.junit.Arquillian;
+import org.jboss.shrinkwrap.api.asset.StringAsset;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ocpsoft.rewrite.annotation.RewriteAnnotationTest;
+import org.ocpsoft.rewrite.test.HttpAction;
+import org.ocpsoft.rewrite.test.RewriteTest;
+import org.ocpsoft.rewrite.test.RewriteTestBase;
+
+@RunWith(Arquillian.class)
+public class CustomConverterTest extends RewriteTestBase
+{
+
+ @Deployment(testable = false)
+ public static WebArchive getDeployment()
+ {
+ return RewriteTest.getDeployment()
+ .addAsLibrary(RewriteAnnotationTest.getRewriteAnnotationArchive())
+ .addAsLibrary(RewriteAnnotationTest.getRewriteCdiArchive())
+ .addClasses(CustomConverterBean.class, LowercaseConverter.class)
+ .addAsWebResource(new StringAsset(
+ "Value: [${customConverterBean.value}]"),
+ "convert.jsp");
+ }
+
+ @Test
+ public void testParameterBindingAnnotation() throws Exception
+ {
+ HttpAction<HttpGet> action = get("/convert/CHRISTIAN/");
+ assertEquals(200, action.getStatusCode());
+ assertTrue(action.getResponseContent().contains("Value: [christian]"));
+ }
+
+}
View
16 config-annotations/src/test/java/org/ocpsoft/rewrite/annotation/convert/LowercaseConverter.java
@@ -0,0 +1,16 @@
+package org.ocpsoft.rewrite.annotation.convert;
+
+import org.ocpsoft.rewrite.bind.Converter;
+import org.ocpsoft.rewrite.context.EvaluationContext;
+import org.ocpsoft.rewrite.event.Rewrite;
+
+public class LowercaseConverter implements Converter<String>
+{
+
+ @Override
+ public String convert(Rewrite event, EvaluationContext context, Object value)
+ {
+ return value.toString().toLowerCase();
+ }
+
+}
View
41 config-annotations/src/test/java/org/ocpsoft/rewrite/annotation/spi/DefaultConverterProviderTest.java
@@ -0,0 +1,41 @@
+package org.ocpsoft.rewrite.annotation.spi;
+
+import static junit.framework.Assert.assertNull;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.math.BigDecimal;
+
+import org.junit.Test;
+import org.ocpsoft.rewrite.bind.Converter;
+import org.ocpsoft.rewrite.context.EvaluationContext;
+import org.ocpsoft.rewrite.event.Rewrite;
+
+public class DefaultConverterProviderTest
+{
+
+ @Test
+ public void testCreateRewriteConverter()
+ {
+ Converter<?> converter = new DefaultConverterProvider().getByType(TestConverter.class);
+ assertNotNull(converter);
+ assertTrue(converter instanceof TestConverter);
+ }
+
+ @Test
+ public void testUnsupportedType()
+ {
+ Converter<?> converter = new DefaultConverterProvider().getByType(BigDecimal.class);
+ assertNull(converter);
+ }
+
+ public static class TestConverter implements Converter<Object>
+ {
+ @Override
+ public Object convert(Rewrite event, EvaluationContext context, Object value)
+ {
+ return null;
+ }
+ }
+
+}
Please sign in to comment.
Something went wrong with that request. Please try again.