github.com/keysonZZZ/kmg@v0.0.0-20151121023212-05317bfd7d39/kmgRpc/kmgRpcJava/java/src/com/google/gson/internal/Excluder.java (about) 1 /* 2 * Copyright (C) 2008 Google Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.google.gson.internal; 18 19 import com.google.gson.ExclusionStrategy; 20 import com.google.gson.FieldAttributes; 21 import com.google.gson.Gson; 22 import com.google.gson.TypeAdapter; 23 import com.google.gson.TypeAdapterFactory; 24 import com.google.gson.annotations.Expose; 25 import com.google.gson.annotations.Since; 26 import com.google.gson.annotations.Until; 27 import com.google.gson.reflect.TypeToken; 28 import com.google.gson.stream.JsonReader; 29 import com.google.gson.stream.JsonWriter; 30 import java.io.IOException; 31 import java.lang.reflect.Field; 32 import java.lang.reflect.Modifier; 33 import java.util.ArrayList; 34 import java.util.Collections; 35 import java.util.List; 36 37 /** 38 * This class selects which fields and types to omit. It is configurable, 39 * supporting version attributes {@link Since} and {@link Until}, modifiers, 40 * synthetic fields, anonymous and local classes, inner classes, and fields with 41 * the {@link Expose} annotation. 42 * 43 * <p>This class is a type adapter factory; types that are excluded will be 44 * adapted to null. It may delegate to another type adapter if only one 45 * direction is excluded. 46 * 47 * @author Joel Leitch 48 * @author Jesse Wilson 49 */ 50 public final class Excluder implements TypeAdapterFactory, Cloneable { 51 private static final double IGNORE_VERSIONS = -1.0d; 52 public static final Excluder DEFAULT = new Excluder(); 53 54 private double version = IGNORE_VERSIONS; 55 private int modifiers = Modifier.TRANSIENT | Modifier.STATIC; 56 private boolean serializeInnerClasses = true; 57 private boolean requireExpose; 58 private List<ExclusionStrategy> serializationStrategies = Collections.emptyList(); 59 private List<ExclusionStrategy> deserializationStrategies = Collections.emptyList(); 60 61 @Override protected Excluder clone() { 62 try { 63 return (Excluder) super.clone(); 64 } catch (CloneNotSupportedException e) { 65 throw new AssertionError(); 66 } 67 } 68 69 public Excluder withVersion(double ignoreVersionsAfter) { 70 Excluder result = clone(); 71 result.version = ignoreVersionsAfter; 72 return result; 73 } 74 75 public Excluder withModifiers(int... modifiers) { 76 Excluder result = clone(); 77 result.modifiers = 0; 78 for (int modifier : modifiers) { 79 result.modifiers |= modifier; 80 } 81 return result; 82 } 83 84 public Excluder disableInnerClassSerialization() { 85 Excluder result = clone(); 86 result.serializeInnerClasses = false; 87 return result; 88 } 89 90 public Excluder excludeFieldsWithoutExposeAnnotation() { 91 Excluder result = clone(); 92 result.requireExpose = true; 93 return result; 94 } 95 96 public Excluder withExclusionStrategy(ExclusionStrategy exclusionStrategy, 97 boolean serialization, boolean deserialization) { 98 Excluder result = clone(); 99 if (serialization) { 100 result.serializationStrategies = new ArrayList<ExclusionStrategy>(serializationStrategies); 101 result.serializationStrategies.add(exclusionStrategy); 102 } 103 if (deserialization) { 104 result.deserializationStrategies 105 = new ArrayList<ExclusionStrategy>(deserializationStrategies); 106 result.deserializationStrategies.add(exclusionStrategy); 107 } 108 return result; 109 } 110 111 public <T> TypeAdapter<T> create(final Gson gson, final TypeToken<T> type) { 112 Class<?> rawType = type.getRawType(); 113 final boolean skipSerialize = excludeClass(rawType, true); 114 final boolean skipDeserialize = excludeClass(rawType, false); 115 116 if (!skipSerialize && !skipDeserialize) { 117 return null; 118 } 119 120 return new TypeAdapter<T>() { 121 /** The delegate is lazily created because it may not be needed, and creating it may fail. */ 122 private TypeAdapter<T> delegate; 123 124 @Override public T read(JsonReader in) throws IOException { 125 if (skipDeserialize) { 126 in.skipValue(); 127 return null; 128 } 129 return delegate().read(in); 130 } 131 132 @Override public void write(JsonWriter out, T value) throws IOException { 133 if (skipSerialize) { 134 out.nullValue(); 135 return; 136 } 137 delegate().write(out, value); 138 } 139 140 private TypeAdapter<T> delegate() { 141 TypeAdapter<T> d = delegate; 142 return d != null 143 ? d 144 : (delegate = gson.getDelegateAdapter(Excluder.this, type)); 145 } 146 }; 147 } 148 149 public boolean excludeField(Field field, boolean serialize) { 150 if ((modifiers & field.getModifiers()) != 0) { 151 return true; 152 } 153 154 if (version != Excluder.IGNORE_VERSIONS 155 && !isValidVersion(field.getAnnotation(Since.class), field.getAnnotation(Until.class))) { 156 return true; 157 } 158 159 if (field.isSynthetic()) { 160 return true; 161 } 162 163 if (requireExpose) { 164 Expose annotation = field.getAnnotation(Expose.class); 165 if (annotation == null || (serialize ? !annotation.serialize() : !annotation.deserialize())) { 166 return true; 167 } 168 } 169 170 if (!serializeInnerClasses && isInnerClass(field.getType())) { 171 return true; 172 } 173 174 if (isAnonymousOrLocal(field.getType())) { 175 return true; 176 } 177 178 List<ExclusionStrategy> list = serialize ? serializationStrategies : deserializationStrategies; 179 if (!list.isEmpty()) { 180 FieldAttributes fieldAttributes = new FieldAttributes(field); 181 for (ExclusionStrategy exclusionStrategy : list) { 182 if (exclusionStrategy.shouldSkipField(fieldAttributes)) { 183 return true; 184 } 185 } 186 } 187 188 return false; 189 } 190 191 public boolean excludeClass(Class<?> clazz, boolean serialize) { 192 if (version != Excluder.IGNORE_VERSIONS 193 && !isValidVersion(clazz.getAnnotation(Since.class), clazz.getAnnotation(Until.class))) { 194 return true; 195 } 196 197 if (!serializeInnerClasses && isInnerClass(clazz)) { 198 return true; 199 } 200 201 if (isAnonymousOrLocal(clazz)) { 202 return true; 203 } 204 205 List<ExclusionStrategy> list = serialize ? serializationStrategies : deserializationStrategies; 206 for (ExclusionStrategy exclusionStrategy : list) { 207 if (exclusionStrategy.shouldSkipClass(clazz)) { 208 return true; 209 } 210 } 211 212 return false; 213 } 214 215 private boolean isAnonymousOrLocal(Class<?> clazz) { 216 return !Enum.class.isAssignableFrom(clazz) 217 && (clazz.isAnonymousClass() || clazz.isLocalClass()); 218 } 219 220 private boolean isInnerClass(Class<?> clazz) { 221 return clazz.isMemberClass() && !isStatic(clazz); 222 } 223 224 private boolean isStatic(Class<?> clazz) { 225 return (clazz.getModifiers() & Modifier.STATIC) != 0; 226 } 227 228 private boolean isValidVersion(Since since, Until until) { 229 return isValidSince(since) && isValidUntil(until); 230 } 231 232 private boolean isValidSince(Since annotation) { 233 if (annotation != null) { 234 double annotationVersion = annotation.value(); 235 if (annotationVersion > version) { 236 return false; 237 } 238 } 239 return true; 240 } 241 242 private boolean isValidUntil(Until annotation) { 243 if (annotation != null) { 244 double annotationVersion = annotation.value(); 245 if (annotationVersion <= version) { 246 return false; 247 } 248 } 249 return true; 250 } 251 }