All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.google.gwt.requestfactory.shared.impl.ProxySerializerImpl Maven / Gradle / Ivy

There is a newer version: 2.10.0
Show newest version
/*
 * Copyright 2010 Google 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 com.google.gwt.requestfactory.shared.impl;

import com.google.gwt.autobean.shared.AutoBean;
import com.google.gwt.autobean.shared.AutoBeanCodex;
import com.google.gwt.autobean.shared.AutoBeanFactory;
import com.google.gwt.autobean.shared.AutoBeanUtils;
import com.google.gwt.autobean.shared.AutoBeanVisitor;
import com.google.gwt.autobean.shared.Splittable;
import com.google.gwt.requestfactory.shared.BaseProxy;
import com.google.gwt.requestfactory.shared.EntityProxy;
import com.google.gwt.requestfactory.shared.EntityProxyId;
import com.google.gwt.requestfactory.shared.ProxySerializer;
import com.google.gwt.requestfactory.shared.ProxyStore;
import com.google.gwt.requestfactory.shared.messages.IdMessage;
import com.google.gwt.requestfactory.shared.messages.IdMessage.Strength;
import com.google.gwt.requestfactory.shared.messages.OperationMessage;

import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * The default implementation of ProxySerializer.
 *
 * 

RequestFactory has moved to * com.google.web.bindery.requestfactory. This package will be * removed in a future version of GWT.

*/ @Deprecated class ProxySerializerImpl extends AbstractRequestContext implements ProxySerializer { /** * Used internally to unwind the stack if data cannot be found in the backing * store. */ private static class NoDataException extends RuntimeException { } private final ProxyStore store; /** * If the user wants to serialize a proxy with a non-persistent id (including * ValueProxy), we'll assign a synthetic id that is local to the store being * used. */ private final Map, SimpleProxyId> syntheticIds = new HashMap, SimpleProxyId>(); /** * The ids of proxies whose content has been reloaded. */ private final Set> restored = new HashSet>(); private final Map, AutoBean> serialized = new HashMap, AutoBean>(); public ProxySerializerImpl(AbstractRequestFactory factory, ProxyStore store) { super(factory, Dialect.STANDARD); this.store = store; } public T deserialize(Class proxyType, String key) { // Fast exit to prevent getOperation from throwing an exception if (store.get(key) == null) { return null; } OperationMessage op = getOperation(proxyType, key); @SuppressWarnings("unchecked") SimpleProxyId id = (SimpleProxyId) getId(op); return doDeserialize(id); } public T deserialize(EntityProxyId id) { return doDeserialize((SimpleEntityProxyId) id); } /** * Replace non-persistent ids with store-local ids. */ @Override public Splittable getSerializedProxyId(SimpleProxyId stableId) { return super.getSerializedProxyId(serializedId(stableId)); } public String serialize(BaseProxy rootObject) { final AutoBean root = AutoBeanUtils.getAutoBean(rootObject); if (root == null) { // Unexpected, some kind of foreign implementation of the BaseProxy? throw new IllegalArgumentException(); } final SimpleProxyId id = serializedId(BaseProxyCategory.stableId(root)); // Only persistent and synthetic ids expected assert !id.isEphemeral() : "Unexpected ephemeral id " + id.toString(); /* * Don't repeatedly serialize the same proxy, unless we're looking at a * mutable instance. */ AutoBean previous = serialized.get(id); if (previous == null || !previous.isFrozen()) { serialized.put(id, root); serializeOneProxy(id, root); root.accept(new AutoBeanVisitor() { @Override public void endVisit(AutoBean bean, Context ctx) { // Avoid unnecessary method call if (bean == root) { return; } if (isEntityType(bean.getType()) || isValueType(bean.getType())) { serialize((BaseProxy) bean.as()); } } @Override public void endVisitCollectionProperty(String propertyName, AutoBean> value, CollectionPropertyContext ctx) { if (value == null) { return; } if (isEntityType(ctx.getElementType()) || isValueType(ctx.getElementType())) { for (Object o : value.as()) { serialize((BaseProxy) o); } } } }); } return getRequestFactory().getHistoryToken(id); } @Override protected AutoBeanFactory getAutoBeanFactory() { return getRequestFactory().getAutoBeanFactory(); } @Override SimpleProxyId getId(IdMessage op) { if (Strength.SYNTHETIC.equals(op.getStrength())) { return getRequestFactory().allocateSyntheticId( getRequestFactory().getTypeFromToken(op.getTypeToken()), op.getSyntheticId()); } return super.getId(op); } @Override AutoBean getProxyForReturnPayloadGraph( SimpleProxyId id) { AutoBean toReturn = super.getProxyForReturnPayloadGraph(id); if (restored.add(id)) { /* * If we haven't seen the id before, use the data in the OperationMessage * to repopulate the properties of the canonical bean for this id. */ OperationMessage op = getOperation(id.getProxyClass(), getRequestFactory().getHistoryToken(id)); this.processReturnOperation(id, op); toReturn.setTag(Constants.STABLE_ID, super.getId(op)); } return toReturn; } /** * Reset all temporary state. */ private void clear() { syntheticIds.clear(); restored.clear(); serialized.clear(); } private T doDeserialize(SimpleProxyId id) { try { return getProxyForReturnPayloadGraph(id).as(); } catch (NoDataException e) { return null; } finally { clear(); } } /** * Load the OperationMessage containing the object state from the backing * store. */ private OperationMessage getOperation(Class proxyType, String key) { Splittable data = store.get(key); if (data == null) { throw new NoDataException(); } OperationMessage op = AutoBeanCodex.decode(MessageFactoryHolder.FACTORY, OperationMessage.class, data).as(); return op; } /** * Convert any non-persistent ids into store-local synthetic ids. */ private SimpleProxyId serializedId( SimpleProxyId stableId) { assert !stableId.isSynthetic(); if (stableId.isEphemeral()) { @SuppressWarnings("unchecked") SimpleProxyId syntheticId = (SimpleProxyId) syntheticIds.get(stableId); if (syntheticId == null) { int nextId = store.nextId(); assert nextId >= 0 : "ProxyStore.nextId() returned a negative number " + nextId; syntheticId = getRequestFactory().allocateSyntheticId( stableId.getProxyClass(), nextId + 1); syntheticIds.put(stableId, syntheticId); } return syntheticId; } return stableId; } private void serializeOneProxy(SimpleProxyId idForSerialization, AutoBean bean) { AutoBean op = makeOperationMessage( serializedId(BaseProxyCategory.stableId(bean)), bean, false); store.put(getRequestFactory().getHistoryToken(idForSerialization), AutoBeanCodex.encode(op)); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy