-
Notifications
You must be signed in to change notification settings - Fork 86
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
First version of @convert(with=SomeConverter.class)
- Loading branch information
Showing
10 changed files
with
364 additions
and
0 deletions.
There are no files selected for viewing
32 changes: 32 additions & 0 deletions
32
config-annotations/src/main/java/org/ocpsoft/rewrite/annotation/Convert.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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(); | ||
} |
116 changes: 116 additions & 0 deletions
116
config-annotations/src/main/java/org/ocpsoft/rewrite/annotation/handler/ConvertHandler.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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); | ||
|
||
} | ||
} | ||
} |
34 changes: 34 additions & 0 deletions
34
config-annotations/src/main/java/org/ocpsoft/rewrite/annotation/spi/ConverterProvider.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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); | ||
} |
51 changes: 51 additions & 0 deletions
51
...nnotations/src/main/java/org/ocpsoft/rewrite/annotation/spi/DefaultConverterProvider.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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; | ||
|
||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
1 change: 1 addition & 0 deletions
1
...src/main/resources/META-INF/services/org.ocpsoft.rewrite.annotation.spi.ConverterProvider
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
org.ocpsoft.rewrite.annotation.spi.DefaultConverterProvider |
30 changes: 30 additions & 0 deletions
30
...annotations/src/test/java/org/ocpsoft/rewrite/annotation/convert/CustomConverterBean.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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; | ||
} | ||
|
||
} |
42 changes: 42 additions & 0 deletions
42
...annotations/src/test/java/org/ocpsoft/rewrite/annotation/convert/CustomConverterTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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]")); | ||
} | ||
|
||
} |
16 changes: 16 additions & 0 deletions
16
...-annotations/src/test/java/org/ocpsoft/rewrite/annotation/convert/LowercaseConverter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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(); | ||
} | ||
|
||
} |
41 changes: 41 additions & 0 deletions
41
...ations/src/test/java/org/ocpsoft/rewrite/annotation/spi/DefaultConverterProviderTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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; | ||
} | ||
} | ||
|
||
} |