implement wrapper to replace Casser.pojo
This commit is contained in:
parent
64d2d6fdd9
commit
5c88f2d4e4
11 changed files with 220 additions and 30 deletions
|
@ -19,6 +19,7 @@ import java.lang.reflect.Method;
|
|||
import java.util.function.Function;
|
||||
|
||||
import casser.core.Instantiator;
|
||||
import casser.core.WrapperInstantiator;
|
||||
|
||||
public interface CasserSettings {
|
||||
|
||||
|
@ -34,4 +35,6 @@ public interface CasserSettings {
|
|||
|
||||
Instantiator getPojoInstantiator();
|
||||
|
||||
WrapperInstantiator getWrapperInstantiator();
|
||||
|
||||
}
|
||||
|
|
|
@ -19,8 +19,10 @@ import java.lang.reflect.Method;
|
|||
import java.util.function.Function;
|
||||
|
||||
import casser.core.Instantiator;
|
||||
import casser.core.WrapperInstantiator;
|
||||
import casser.core.reflect.ReflectionDslInstantiator;
|
||||
import casser.core.reflect.ReflectionPojoInstantiator;
|
||||
import casser.core.reflect.ReflectionWrapperInstantiator;
|
||||
import casser.mapping.convert.CamelCaseToUnderscoreConverter;
|
||||
import casser.mapping.convert.MethodNameToPropertyConverter;
|
||||
|
||||
|
@ -56,6 +58,9 @@ public class DefaultCasserSettings implements CasserSettings {
|
|||
return ReflectionPojoInstantiator.INSTANCE;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public WrapperInstantiator getWrapperInstantiator() {
|
||||
return ReflectionWrapperInstantiator.INSTANCE;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -15,15 +15,12 @@
|
|||
*/
|
||||
package casser.core;
|
||||
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
import casser.config.CasserSettings;
|
||||
import casser.config.DefaultCasserSettings;
|
||||
import casser.core.reflect.DslInvocationHandler;
|
||||
import casser.core.reflect.PojoInvocationHandler;
|
||||
import casser.mapping.convert.UDTValueWritable;
|
||||
|
||||
import com.datastax.driver.core.Cluster;
|
||||
import com.datastax.driver.core.Session;
|
||||
|
@ -98,4 +95,12 @@ public final class Casser {
|
|||
return settings.getPojoInstantiator().instantiate(iface, classLoader);
|
||||
}
|
||||
|
||||
public static <E> E wrap(Map<String, Object> map, Class<E> iface) {
|
||||
return wrap(map, iface, iface.getClassLoader());
|
||||
}
|
||||
|
||||
public static <E> E wrap(Map<String, Object> map, Class<E> iface, ClassLoader classLoader) {
|
||||
return settings.getWrapperInstantiator().instantiate(map, iface, classLoader);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
24
src/main/java/casser/core/WrapperInstantiator.java
Normal file
24
src/main/java/casser/core/WrapperInstantiator.java
Normal file
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* Copyright (C) 2015 Noorq, Inc.
|
||||
*
|
||||
* 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 casser.core;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public interface WrapperInstantiator {
|
||||
|
||||
<E> E instantiate(Map<String, Object> map, Class<E> iface, ClassLoader classLoader);
|
||||
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright (C) 2015 Noorq, Inc.
|
||||
*
|
||||
* 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 casser.core.reflect;
|
||||
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.util.Map;
|
||||
|
||||
import casser.core.WrapperInstantiator;
|
||||
import casser.mapping.MapExportable;
|
||||
|
||||
public enum ReflectionWrapperInstantiator implements WrapperInstantiator {
|
||||
|
||||
INSTANCE;
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <E> E instantiate(Map<String, Object> map, Class<E> iface,
|
||||
ClassLoader classLoader) {
|
||||
|
||||
WrapperInvocationHandler<E> handler = new WrapperInvocationHandler<E>(map, iface);
|
||||
E proxy = (E) Proxy.newProxyInstance(
|
||||
classLoader,
|
||||
new Class[] { iface, MapExportable.class },
|
||||
handler);
|
||||
return proxy;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* Copyright (C) 2015 Noorq, Inc.
|
||||
*
|
||||
* 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 casser.core.reflect;
|
||||
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
import casser.mapping.MapExportable;
|
||||
import casser.support.CasserException;
|
||||
|
||||
public class WrapperInvocationHandler<E> implements InvocationHandler {
|
||||
|
||||
private final Map<String, Object> map;
|
||||
private final Class<E> iface;
|
||||
|
||||
public WrapperInvocationHandler(Map<String, Object> map, Class<E> iface) {
|
||||
this.map = map;
|
||||
this.iface = iface;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object invoke(Object proxy, Method method, Object[] args)
|
||||
throws Throwable {
|
||||
|
||||
if (method.getParameterCount() != 0 || method.getReturnType() == void.class) {
|
||||
throw new CasserException("invalid getter method " + method);
|
||||
}
|
||||
|
||||
String methodName = method.getName();
|
||||
|
||||
if ("toString".equals(methodName)) {
|
||||
return "Wrapper:" + iface + ":" + map.toString();
|
||||
}
|
||||
|
||||
if (MapExportable.TO_MAP_METHOD.equals(methodName)) {
|
||||
return Collections.unmodifiableMap(map);
|
||||
}
|
||||
|
||||
Object value = map.get(methodName);
|
||||
|
||||
if (value == null) {
|
||||
|
||||
Class<?> returnType = method.getReturnType();
|
||||
|
||||
if (returnType.isPrimitive()) {
|
||||
|
||||
DefaultPrimitiveTypes type = DefaultPrimitiveTypes.lookup(returnType);
|
||||
if (type == null) {
|
||||
throw new CasserException("unknown primitive type " + returnType);
|
||||
}
|
||||
|
||||
return type.getDefaultValue();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
}
|
26
src/main/java/casser/mapping/MapExportable.java
Normal file
26
src/main/java/casser/mapping/MapExportable.java
Normal file
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Copyright (C) 2015 Noorq, Inc.
|
||||
*
|
||||
* 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 casser.mapping;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public interface MapExportable {
|
||||
|
||||
public static final String TO_MAP_METHOD = "toMap";
|
||||
|
||||
Map<String, Object> toMap();
|
||||
|
||||
}
|
|
@ -15,17 +15,14 @@
|
|||
*/
|
||||
package casser.test.unit.core.dsl;
|
||||
|
||||
import casser.mapping.MapExportable;
|
||||
import casser.mapping.Table;
|
||||
|
||||
@Table
|
||||
public interface Account {
|
||||
public interface Account extends MapExportable {
|
||||
|
||||
String getId();
|
||||
Long id();
|
||||
|
||||
void setId(String acc);
|
||||
|
||||
boolean isActive();
|
||||
|
||||
void setActive(boolean a);
|
||||
boolean active();
|
||||
|
||||
}
|
||||
|
|
|
@ -29,12 +29,14 @@ public class DslTest {
|
|||
|
||||
System.out.println("account = " + account);
|
||||
|
||||
/*
|
||||
try {
|
||||
account.getId();
|
||||
account.id();
|
||||
}
|
||||
catch(DslPropertyException e) {
|
||||
System.out.println(e.getProperty());
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -15,44 +15,52 @@
|
|||
*/
|
||||
package casser.test.unit.core.dsl;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import casser.core.Casser;
|
||||
import casser.support.CasserException;
|
||||
|
||||
public class PojoTest {
|
||||
|
||||
Account account = Casser.pojo(Account.class);
|
||||
public class WrapperTest {
|
||||
|
||||
@Test
|
||||
public void testObject() throws Exception {
|
||||
public void testWrap() throws Exception {
|
||||
|
||||
Assert.assertNull(account.getId());
|
||||
Map<String, Object> map = new HashMap<String, Object>();
|
||||
|
||||
account.setId("testAcc");
|
||||
map.put("id", 123L);
|
||||
map.put("active", Boolean.TRUE);
|
||||
map.put("unknownField", "he-he");
|
||||
|
||||
Assert.assertEquals("testAcc", account.getId());
|
||||
Account account = Casser.wrap(map, Account.class);
|
||||
|
||||
Assert.assertEquals(Long.valueOf(123L), account.id());
|
||||
Assert.assertTrue(account.active());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPrimitive() throws Exception {
|
||||
|
||||
Assert.assertFalse(account.isActive());
|
||||
Map<String, Object> map = new HashMap<String, Object>();
|
||||
|
||||
account.setActive(true);
|
||||
map.put("id", 123L);
|
||||
|
||||
Assert.assertEquals(true, account.isActive());
|
||||
Account account = Casser.wrap(map, Account.class);
|
||||
|
||||
Assert.assertFalse(account.active());
|
||||
|
||||
}
|
||||
|
||||
@Test(expected=CasserException.class)
|
||||
public void testWrongMethods() throws Exception {
|
||||
|
||||
Casser.pojo(WrongAccount.class);
|
||||
WrongAccount wrongAccount = Casser.wrap(new HashMap<String, Object>(), WrongAccount.class);
|
||||
|
||||
wrongAccount.id();
|
||||
|
||||
}
|
||||
|
|
@ -17,6 +17,6 @@ package casser.test.unit.core.dsl;
|
|||
|
||||
public interface WrongAccount {
|
||||
|
||||
void getId();
|
||||
void id();
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue