mirror of https://github.com/apache/jclouds.git
helpers for empty collections
This commit is contained in:
parent
0b31622267
commit
49877c8f06
|
@ -26,6 +26,7 @@ import org.jclouds.javax.annotation.Nullable;
|
|||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.common.base.Optional;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
/**
|
||||
* Utilities for using {@link IterableWithMarker}s.
|
||||
|
@ -34,6 +35,9 @@ import com.google.common.base.Optional;
|
|||
*/
|
||||
@Beta
|
||||
public class IterableWithMarkers {
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
public static final IterableWithMarker EMPTY = from(ImmutableSet.of());
|
||||
|
||||
/**
|
||||
* Returns a paginated iterable containing the given elements and null marker.
|
||||
|
|
|
@ -35,6 +35,17 @@ import com.google.common.collect.ImmutableSet;
|
|||
*/
|
||||
@Beta
|
||||
public class PagedIterables {
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
public static final PagedIterable EMPTY = new PagedIterable() {
|
||||
|
||||
@Override
|
||||
public Iterator<IterableWithMarker> iterator() {
|
||||
return ImmutableSet.of(IterableWithMarkers.EMPTY).iterator();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* @param only
|
||||
* the only page of data
|
||||
|
|
|
@ -39,6 +39,8 @@ import org.jclouds.json.Json;
|
|||
import org.jclouds.json.internal.DeserializationConstructorAndReflectiveTypeAdapterFactory;
|
||||
import org.jclouds.json.internal.EnumTypeAdapterThatReturnsFromValue;
|
||||
import org.jclouds.json.internal.GsonWrapper;
|
||||
import org.jclouds.json.internal.IgnoreNullFluentIterableTypeAdapterFactory;
|
||||
import org.jclouds.json.internal.IgnoreNullIterableTypeAdapterFactory;
|
||||
import org.jclouds.json.internal.IgnoreNullMapTypeAdapterFactory;
|
||||
import org.jclouds.json.internal.IgnoreNullMultimapTypeAdapterFactory;
|
||||
import org.jclouds.json.internal.IgnoreNullSetTypeAdapterFactory;
|
||||
|
@ -81,7 +83,10 @@ public class GsonModule extends AbstractModule {
|
|||
@Provides
|
||||
@Singleton
|
||||
Gson provideGson(TypeAdapter<JsonBall> jsonAdapter, DateAdapter adapter, ByteListAdapter byteListAdapter,
|
||||
ByteArrayAdapter byteArrayAdapter, PropertiesAdapter propertiesAdapter, JsonAdapterBindings bindings)
|
||||
ByteArrayAdapter byteArrayAdapter, PropertiesAdapter propertiesAdapter, JsonAdapterBindings bindings,
|
||||
OptionalTypeAdapterFactory optional, IgnoreNullSetTypeAdapterFactory set,
|
||||
IgnoreNullMapTypeAdapterFactory map, IgnoreNullMultimapTypeAdapterFactory multimap,
|
||||
IgnoreNullIterableTypeAdapterFactory iterable, IgnoreNullFluentIterableTypeAdapterFactory fluentIterable)
|
||||
throws Exception {
|
||||
|
||||
FieldNamingStrategy serializationPolicy = new AnnotationOrNameFieldNamingStrategy(new ExtractSerializedName(),
|
||||
|
@ -96,10 +101,12 @@ public class GsonModule extends AbstractModule {
|
|||
}.getType(), byteListAdapter.nullSafe());
|
||||
builder.registerTypeAdapter(byte[].class, byteArrayAdapter.nullSafe());
|
||||
builder.registerTypeAdapter(JsonBall.class, jsonAdapter.nullSafe());
|
||||
builder.registerTypeAdapterFactory(new OptionalTypeAdapterFactory());
|
||||
builder.registerTypeAdapterFactory(new IgnoreNullSetTypeAdapterFactory());
|
||||
builder.registerTypeAdapterFactory(new IgnoreNullMapTypeAdapterFactory());
|
||||
builder.registerTypeAdapterFactory(new IgnoreNullMultimapTypeAdapterFactory());
|
||||
builder.registerTypeAdapterFactory(optional);
|
||||
builder.registerTypeAdapterFactory(set);
|
||||
builder.registerTypeAdapterFactory(map);
|
||||
builder.registerTypeAdapterFactory(multimap);
|
||||
builder.registerTypeAdapterFactory(iterable);
|
||||
builder.registerTypeAdapterFactory(fluentIterable);
|
||||
|
||||
AnnotationConstructorNamingStrategy deserializationPolicy =
|
||||
new AnnotationConstructorNamingStrategy(
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
/**
|
||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||
* contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. jclouds licenses this file
|
||||
* to you 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.jclouds.json.internal;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
import com.google.common.collect.FluentIterable;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableList.Builder;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.TypeAdapter;
|
||||
import com.google.gson.TypeAdapterFactory;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import com.google.gson.stream.JsonReader;
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
|
||||
/**
|
||||
* Eliminates null values when deserializing FluentIterables
|
||||
* <p/>
|
||||
* Treats [null] as the empty set; [A, null] as [A]; etc.
|
||||
*
|
||||
* @author Adam Lowe
|
||||
*/
|
||||
public class IgnoreNullFluentIterableTypeAdapterFactory implements TypeAdapterFactory {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
|
||||
Type type = typeToken.getType();
|
||||
if (typeToken.getRawType() != FluentIterable.class || !(type instanceof ParameterizedType)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Type elementType = ((ParameterizedType) type).getActualTypeArguments()[0];
|
||||
TypeAdapter<?> elementAdapter = gson.getAdapter(TypeToken.get(elementType));
|
||||
return (TypeAdapter<T>) newFluentIterableAdapter(elementAdapter);
|
||||
}
|
||||
|
||||
private <E> TypeAdapter<FluentIterable<E>> newFluentIterableAdapter(final TypeAdapter<E> elementAdapter) {
|
||||
return new TypeAdapter<FluentIterable<E>>() {
|
||||
public void write(JsonWriter out, FluentIterable<E> value) throws IOException {
|
||||
out.beginArray();
|
||||
for (E element : value) {
|
||||
elementAdapter.write(out, element);
|
||||
}
|
||||
out.endArray();
|
||||
}
|
||||
|
||||
public FluentIterable<E> read(JsonReader in) throws IOException {
|
||||
in.beginArray();
|
||||
Builder<E> builder = ImmutableList.<E>builder();
|
||||
while (in.hasNext()) {
|
||||
E element = elementAdapter.read(in);
|
||||
if (element != null) builder.add(element);
|
||||
}
|
||||
in.endArray();
|
||||
return FluentIterable.from(builder.build());
|
||||
}
|
||||
}.nullSafe();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
/**
|
||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||
* contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. jclouds licenses this file
|
||||
* to you 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.jclouds.json.internal;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableList.Builder;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.TypeAdapter;
|
||||
import com.google.gson.TypeAdapterFactory;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import com.google.gson.stream.JsonReader;
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
|
||||
/**
|
||||
* Eliminates null values when deserializing Iterables
|
||||
* <p/>
|
||||
* Treats [null] as the empty set; [A, null] as [A]; etc.
|
||||
*
|
||||
* @author Adam Lowe
|
||||
*/
|
||||
public class IgnoreNullIterableTypeAdapterFactory implements TypeAdapterFactory {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
|
||||
Type type = typeToken.getType();
|
||||
if (typeToken.getRawType() != Iterable.class || !(type instanceof ParameterizedType)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Type elementType = ((ParameterizedType) type).getActualTypeArguments()[0];
|
||||
TypeAdapter<?> elementAdapter = gson.getAdapter(TypeToken.get(elementType));
|
||||
return (TypeAdapter<T>) newIterableAdapter(elementAdapter);
|
||||
}
|
||||
|
||||
private <E> TypeAdapter<Iterable<E>> newIterableAdapter(final TypeAdapter<E> elementAdapter) {
|
||||
return new TypeAdapter<Iterable<E>>() {
|
||||
public void write(JsonWriter out, Iterable<E> value) throws IOException {
|
||||
out.beginArray();
|
||||
for (E element : value) {
|
||||
elementAdapter.write(out, element);
|
||||
}
|
||||
out.endArray();
|
||||
}
|
||||
|
||||
public Iterable<E> read(JsonReader in) throws IOException {
|
||||
in.beginArray();
|
||||
Builder<E> builder = ImmutableList.<E>builder();
|
||||
while (in.hasNext()) {
|
||||
E element = elementAdapter.read(in);
|
||||
if (element != null) builder.add(element);
|
||||
}
|
||||
in.endArray();
|
||||
return builder.build();
|
||||
}
|
||||
}.nullSafe();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
/**
|
||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||
* contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. jclouds licenses this file
|
||||
* to you 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.jclouds.rest.functions;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.http.functions.ReturnTrueOn404;
|
||||
import org.jclouds.rest.ResourceNotFoundException;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.common.collect.FluentIterable;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Iterables;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Singleton
|
||||
public class ReturnEmptyFluentIterableOnNotFoundOr404 implements Function<Exception, Object> {
|
||||
private final ReturnTrueOn404 rto404;
|
||||
|
||||
@Inject
|
||||
private ReturnEmptyFluentIterableOnNotFoundOr404(ReturnTrueOn404 rto404) {
|
||||
this.rto404 = checkNotNull(rto404, "rto404");
|
||||
}
|
||||
|
||||
public Object apply(Exception from) {
|
||||
Iterable<ResourceNotFoundException> throwables = Iterables.filter(Throwables.getCausalChain(from),
|
||||
ResourceNotFoundException.class);
|
||||
if (Iterables.size(throwables) >= 1) {
|
||||
return FluentIterable.from(ImmutableSet.of());
|
||||
} else if (rto404.apply(from)) {
|
||||
return FluentIterable.from(ImmutableSet.of());
|
||||
}
|
||||
throw Throwables.propagate(from);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
/**
|
||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||
* contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. jclouds licenses this file
|
||||
* to you 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.jclouds.rest.functions;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.collect.IterableWithMarkers;
|
||||
import org.jclouds.http.functions.ReturnTrueOn404;
|
||||
import org.jclouds.rest.ResourceNotFoundException;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.common.collect.Iterables;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Singleton
|
||||
public class ReturnEmptyIterableWithMarkerOnNotFoundOr404 implements Function<Exception, Object> {
|
||||
private final ReturnTrueOn404 rto404;
|
||||
|
||||
@Inject
|
||||
private ReturnEmptyIterableWithMarkerOnNotFoundOr404(ReturnTrueOn404 rto404) {
|
||||
this.rto404 = checkNotNull(rto404, "rto404");
|
||||
}
|
||||
|
||||
public Object apply(Exception from) {
|
||||
Iterable<ResourceNotFoundException> throwables = Iterables.filter(Throwables.getCausalChain(from),
|
||||
ResourceNotFoundException.class);
|
||||
if (Iterables.size(throwables) >= 1) {
|
||||
return IterableWithMarkers.EMPTY;
|
||||
} else if (rto404.apply(from)) {
|
||||
return IterableWithMarkers.EMPTY;
|
||||
}
|
||||
throw Throwables.propagate(from);
|
||||
}
|
||||
|
||||
}
|
|
@ -20,8 +20,6 @@ package org.jclouds.rest.functions;
|
|||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
|
|
|
@ -20,8 +20,6 @@ package org.jclouds.rest.functions;
|
|||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
|
|
|
@ -30,7 +30,6 @@ import com.google.common.base.Function;
|
|||
import com.google.common.base.Throwables;
|
||||
import com.google.common.collect.ImmutableMultimap;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Multimap;
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
/**
|
||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||
* contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. jclouds licenses this file
|
||||
* to you 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.jclouds.rest.functions;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.collect.PagedIterables;
|
||||
import org.jclouds.http.functions.ReturnTrueOn404;
|
||||
import org.jclouds.rest.ResourceNotFoundException;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.common.collect.Iterables;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Singleton
|
||||
public class ReturnEmptyPagedIterableOnNotFoundOr404 implements Function<Exception, Object> {
|
||||
private final ReturnTrueOn404 rto404;
|
||||
|
||||
@Inject
|
||||
private ReturnEmptyPagedIterableOnNotFoundOr404(ReturnTrueOn404 rto404) {
|
||||
this.rto404 = checkNotNull(rto404, "rto404");
|
||||
}
|
||||
|
||||
public Object apply(Exception from) {
|
||||
Iterable<ResourceNotFoundException> throwables = Iterables.filter(Throwables.getCausalChain(from),
|
||||
ResourceNotFoundException.class);
|
||||
if (Iterables.size(throwables) >= 1) {
|
||||
return PagedIterables.EMPTY;
|
||||
} else if (rto404.apply(from)) {
|
||||
return PagedIterables.EMPTY;
|
||||
}
|
||||
throw Throwables.propagate(from);
|
||||
}
|
||||
|
||||
}
|
|
@ -20,8 +20,6 @@ package org.jclouds.rest.functions;
|
|||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
|
|
Loading…
Reference in New Issue