com.sun.jna.NativeMappedConverter Maven / Gradle / Ivy
/* Copyright (c) 2007 Timothy Wall, All Rights Reserved
*
* The contents of this file is dual-licensed under 2
* alternative Open Source/Free licenses: LGPL 2.1 or later and
* Apache License 2.0. (starting with JNA version 4.0.0).
*
* You can freely decide which license you want to apply to
* the project.
*
* You may obtain a copy of the LGPL License at:
*
* http://www.gnu.org/licenses/licenses.html
*
* A copy is also included in the downloadable source code package
* containing JNA, in file "LGPL2.1".
*
* You may obtain a copy of the Apache License at:
*
* http://www.apache.org/licenses/
*
* A copy is also included in the downloadable source code package
* containing JNA, in file "AL2.0".
*/
package com.sun.jna;
import java.lang.ref.Reference;
import java.lang.ref.SoftReference;
import java.util.Map;
import java.util.WeakHashMap;
/** Provides type conversion for instances of {@link NativeMapped}. */
public class NativeMappedConverter implements TypeConverter {
private static final Map, Reference> converters =
new WeakHashMap, Reference>();
private final Class> type;
private final Class> nativeType;
private final NativeMapped instance;
public static NativeMappedConverter getInstance(Class> cls) {
synchronized(converters) {
Reference r = converters.get(cls);
NativeMappedConverter nmc = r != null ? r.get() : null;
if (nmc == null) {
nmc = new NativeMappedConverter(cls);
converters.put(cls, new SoftReference(nmc));
}
return nmc;
}
}
public NativeMappedConverter(Class> type) {
if (!NativeMapped.class.isAssignableFrom(type))
throw new IllegalArgumentException("Type must derive from " + NativeMapped.class);
this.type = type;
this.instance = defaultValue();
this.nativeType = instance.nativeType();
}
public NativeMapped defaultValue() {
try {
return (NativeMapped)type.newInstance();
} catch (InstantiationException e) {
String msg = "Can't create an instance of " + type
+ ", requires a no-arg constructor: " + e;
throw new IllegalArgumentException(msg);
} catch (IllegalAccessException e) {
String msg = "Not allowed to create an instance of " + type
+ ", requires a public, no-arg constructor: " + e;
throw new IllegalArgumentException(msg);
}
}
@Override
public Object fromNative(Object nativeValue, FromNativeContext context) {
return instance.fromNative(nativeValue, context);
}
@Override
public Class> nativeType() {
return nativeType;
}
@Override
public Object toNative(Object value, ToNativeContext context) {
if (value == null) {
if (Pointer.class.isAssignableFrom(nativeType)) {
return null;
}
value = defaultValue();
}
return ((NativeMapped)value).toNative();
}
}