blob: e4c50f2f3d57af6262254aa1dc3b775f812b491c [file] [log] [blame]
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<!--NewPage-->
<HTML>
<HEAD>
<!-- Generated by javadoc (build 1.6.0_23) on Fri Dec 30 23:30:48 PST 2011 -->
<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
<TITLE>
TypeAdapterFactory (Gson 2.1 API)
</TITLE>
<META NAME="date" CONTENT="2011-12-30">
<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../stylesheet.css" TITLE="Style">
<SCRIPT type="text/javascript">
function windowTitle()
{
if (location.href.indexOf('is-external=true') == -1) {
parent.document.title="TypeAdapterFactory (Gson 2.1 API)";
}
}
</SCRIPT>
<NOSCRIPT>
</NOSCRIPT>
</HEAD>
<BODY BGCOLOR="white" onload="windowTitle();">
<HR>
<!-- ========= START OF TOP NAVBAR ======= -->
<A NAME="navbar_top"><!-- --></A>
<A HREF="#skip-navbar_top" title="Skip navigation links"></A>
<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
<TR>
<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
<A NAME="navbar_top_firstrow"><!-- --></A>
<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
<TR ALIGN="center" VALIGN="top">
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
<TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="class-use/TypeAdapterFactory.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
</TR>
</TABLE>
</TD>
<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
</EM>
</TD>
</TR>
<TR>
<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
&nbsp;<A HREF="../../../com/google/gson/TypeAdapter.html" title="class in com.google.gson"><B>PREV CLASS</B></A>&nbsp;
&nbsp;NEXT CLASS</FONT></TD>
<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
<A HREF="../../../index.html?com/google/gson/TypeAdapterFactory.html" target="_top"><B>FRAMES</B></A> &nbsp;
&nbsp;<A HREF="TypeAdapterFactory.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
&nbsp;<SCRIPT type="text/javascript">
<!--
if(window==top) {
document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
}
//-->
</SCRIPT>
<NOSCRIPT>
<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
</NOSCRIPT>
</FONT></TD>
</TR>
<TR>
<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
DETAIL:&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
</TR>
</TABLE>
<A NAME="skip-navbar_top"></A>
<!-- ========= END OF TOP NAVBAR ========= -->
<HR>
<!-- ======== START OF CLASS DATA ======== -->
<H2>
<FONT SIZE="-1">
com.google.gson</FONT>
<BR>
Interface TypeAdapterFactory</H2>
<HR>
<DL>
<DT><PRE>public interface <B>TypeAdapterFactory</B></DL>
</PRE>
<P>
Creates type adapters for set of related types. Type adapter factories are
most useful when several types share similar structure in their JSON form.
<h3>Example: Converting enums to lowercase</h3>
In this example, we implement a factory that creates type adapters for all
enums. The type adapters will write enums in lowercase, despite the fact
that they're defined in <code>CONSTANT_CASE</code> in the corresponding Java
model: <pre> <code>public class LowercaseEnumTypeAdapterFactory implements TypeAdapter.Factory {
public &lt;T&gt; TypeAdapter&lt;T&gt; create(Gson gson, TypeToken&lt;T&gt; type) {
Class&lt;T&gt; rawType = (Class&lt;T&gt;) type.getRawType();
if (!rawType.isEnum()) {
return null;
}
final Map&lt;String, T&gt; lowercaseToConstant = new HashMap&lt;String, T&gt;();
for (T constant : rawType.getEnumConstants()) {
lowercaseToConstant.put(toLowercase(constant), constant);
}
return new TypeAdapter&lt;T&gt;() {
public void write(JsonWriter out, T value) throws IOException {
if (value == null) {
out.nullValue();
} else {
out.value(toLowercase(value));
}
}
public T read(JsonReader reader) throws IOException {
if (reader.peek() == JsonToken.NULL) {
reader.nextNull();
return null;
} else {
return lowercaseToConstant.get(reader.nextString());
}
}
};
}
private String toLowercase(Object o) {
return o.toString().toLowerCase(Locale.US);
}
}
</code></pre>
<p>Type adapter factories select which types they provide type adapters
for. If a factory cannot support a given type, it must return null when
that type is passed to <A HREF="../../../com/google/gson/TypeAdapterFactory.html#create(com.google.gson.Gson, com.google.gson.reflect.TypeToken)"><CODE>create(com.google.gson.Gson, com.google.gson.reflect.TypeToken<T>)</CODE></A>. Factories should expect <code>create()</code> to be called on them for many types and should return null for
most of those types. In the above example the factory returns null for
calls to <code>create()</code> where <code>type</code> is not an enum.
<p>A factory is typically called once per type, but the returned type
adapter may be used many times. It is most efficient to do expensive work
like reflection in <code>create()</code> so that the type adapter's <code>read()</code> and <code>write()</code> methods can be very fast. In this example the
mapping from lowercase name to enum value is computed eagerly.
<p>As with type adapters, factories must be <i>registered</i> with a <A HREF="../../../com/google/gson/GsonBuilder.html" title="class in com.google.gson"><CODE>GsonBuilder</CODE></A> for them to take effect: <pre> <code>GsonBuilder builder = new GsonBuilder();
builder.registerTypeAdapterFactory(new LowercaseEnumTypeAdapterFactory());
...
Gson gson = builder.create();
</code></pre>
If multiple factories support the same type, the factory registered earlier
takes precedence.
<h3>Example: composing other type adapters</h3>
In this example we implement a factory for Guava's <code>Multiset</code>
collection type. The factory can be used to create type adapters for
multisets of any element type: the type adapter for <code>Multiset&lt;String&gt;</code> is different from the type adapter for <code>Multiset&lt;URL&gt;</code>.
<p>The type adapter <i>delegates</i> to another type adapter for the
multiset elements. It figures out the element type by reflecting on the
multiset's type token. A <code>Gson</code> is passed in to <code>create</code> for
just this purpose: <pre> <code>public class MultisetTypeAdapterFactory implements TypeAdapter.Factory {
public &lt;T&gt; TypeAdapter&lt;T&gt; create(Gson gson, TypeToken&lt;T&gt; typeToken) {
Type type = typeToken.getType();
if (typeToken.getRawType() != Multiset.class
|| !(type instanceof ParameterizedType)) {
return null;
}
Type elementType = ((ParameterizedType) type).getActualTypeArguments()[0];
TypeAdapter&lt;?&gt; elementAdapter = gson.getAdapter(TypeToken.get(elementType));
return (TypeAdapter&lt;T&gt;) newMultisetAdapter(elementAdapter);
}
private &lt;E&gt; TypeAdapter&lt;Multiset&lt;E&gt;&gt; newMultisetAdapter(
final TypeAdapter&lt;E&gt; elementAdapter) {
return new TypeAdapter&lt;Multiset&lt;E&gt;&gt;() {
public void write(JsonWriter out, Multiset&lt;E&gt; value) throws IOException {
if (value == null) {
out.nullValue();
return;
}
out.beginArray();
for (Multiset.Entry&lt;E&gt; entry : value.entrySet()) {
out.value(entry.getCount());
elementAdapter.write(out, entry.getElement());
}
out.endArray();
}
public Multiset&lt;E&gt; read(JsonReader in) throws IOException {
if (in.peek() == JsonToken.NULL) {
in.nextNull();
return null;
}
Multiset&lt;E&gt; result = LinkedHashMultiset.create();
in.beginArray();
while (in.hasNext()) {
int count = in.nextInt();
E element = elementAdapter.read(in);
result.add(element, count);
}
in.endArray();
return result;
}
};
}
}
</code></pre>
Delegating from one type adapter to another is extremely powerful; it's
the foundation of how Gson converts Java objects and collections. Whenever
possible your factory should retrieve its delegate type adapter in the
<code>create()</code> method; this ensures potentially-expensive type adapter
creation happens only once.
<P>
<P>
<DL>
<DT><B>Since:</B></DT>
<DD>2.1</DD>
</DL>
<HR>
<P>
<!-- ========== METHOD SUMMARY =========== -->
<A NAME="method_summary"><!-- --></A>
<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
<TH ALIGN="left" COLSPAN="2"><FONT SIZE="+2">
<B>Method Summary</B></FONT></TH>
</TR>
<TR BGCOLOR="white" CLASS="TableRowColor">
<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
<CODE>
<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="0" SUMMARY="">
<TR ALIGN="right" VALIGN="">
<TD NOWRAP><FONT SIZE="-1">
<CODE>&lt;T&gt; <A HREF="../../../com/google/gson/TypeAdapter.html" title="class in com.google.gson">TypeAdapter</A>&lt;T&gt;</CODE></FONT></TD>
</TR>
</TABLE>
</CODE></FONT></TD>
<TD><CODE><B><A HREF="../../../com/google/gson/TypeAdapterFactory.html#create(com.google.gson.Gson, com.google.gson.reflect.TypeToken)">create</A></B>(<A HREF="../../../com/google/gson/Gson.html" title="class in com.google.gson">Gson</A>&nbsp;gson,
<A HREF="../../../com/google/gson/reflect/TypeToken.html" title="class in com.google.gson.reflect">TypeToken</A>&lt;T&gt;&nbsp;type)</CODE>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns a type adapter for <code>type</code>, or null if this factory doesn't
support <code>type</code>.</TD>
</TR>
</TABLE>
&nbsp;
<P>
<!-- ============ METHOD DETAIL ========== -->
<A NAME="method_detail"><!-- --></A>
<TABLE BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
<TH ALIGN="left" COLSPAN="1"><FONT SIZE="+2">
<B>Method Detail</B></FONT></TH>
</TR>
</TABLE>
<A NAME="create(com.google.gson.Gson, com.google.gson.reflect.TypeToken)"><!-- --></A><H3>
create</H3>
<PRE>
&lt;T&gt; <A HREF="../../../com/google/gson/TypeAdapter.html" title="class in com.google.gson">TypeAdapter</A>&lt;T&gt; <B>create</B>(<A HREF="../../../com/google/gson/Gson.html" title="class in com.google.gson">Gson</A>&nbsp;gson,
<A HREF="../../../com/google/gson/reflect/TypeToken.html" title="class in com.google.gson.reflect">TypeToken</A>&lt;T&gt;&nbsp;type)</PRE>
<DL>
<DD>Returns a type adapter for <code>type</code>, or null if this factory doesn't
support <code>type</code>.
<P>
<DD><DL>
</DL>
</DD>
</DL>
<!-- ========= END OF CLASS DATA ========= -->
<HR>
<!-- ======= START OF BOTTOM NAVBAR ====== -->
<A NAME="navbar_bottom"><!-- --></A>
<A HREF="#skip-navbar_bottom" title="Skip navigation links"></A>
<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0" SUMMARY="">
<TR>
<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
<A NAME="navbar_bottom_firstrow"><!-- --></A>
<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3" SUMMARY="">
<TR ALIGN="center" VALIGN="top">
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A>&nbsp;</TD>
<TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT>&nbsp;</TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="class-use/TypeAdapterFactory.html"><FONT CLASS="NavBarFont1"><B>Use</B></FONT></A>&nbsp;</TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A>&nbsp;</TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A>&nbsp;</TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A>&nbsp;</TD>
<TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A>&nbsp;</TD>
</TR>
</TABLE>
</TD>
<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
</EM>
</TD>
</TR>
<TR>
<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
&nbsp;<A HREF="../../../com/google/gson/TypeAdapter.html" title="class in com.google.gson"><B>PREV CLASS</B></A>&nbsp;
&nbsp;NEXT CLASS</FONT></TD>
<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
<A HREF="../../../index.html?com/google/gson/TypeAdapterFactory.html" target="_top"><B>FRAMES</B></A> &nbsp;
&nbsp;<A HREF="TypeAdapterFactory.html" target="_top"><B>NO FRAMES</B></A> &nbsp;
&nbsp;<SCRIPT type="text/javascript">
<!--
if(window==top) {
document.writeln('<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>');
}
//-->
</SCRIPT>
<NOSCRIPT>
<A HREF="../../../allclasses-noframe.html"><B>All Classes</B></A>
</NOSCRIPT>
</FONT></TD>
</TR>
<TR>
<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
SUMMARY:&nbsp;NESTED&nbsp;|&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_summary">METHOD</A></FONT></TD>
<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
DETAIL:&nbsp;FIELD&nbsp;|&nbsp;CONSTR&nbsp;|&nbsp;<A HREF="#method_detail">METHOD</A></FONT></TD>
</TR>
</TABLE>
<A NAME="skip-navbar_bottom"></A>
<!-- ======== END OF BOTTOM NAVBAR ======= -->
<HR>
Copyright &#169; 2008-2011 <a href="http://www.google.com">Google, Inc.</a>. All Rights Reserved.
</BODY>
</HTML>