Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  // Copyright 2007, 2008, 2009 The Apache Software Foundation
  //
  // 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 org.apache.tapestry5.internal.services;
 
 
 import java.util.Map;

Manages client-persistent values on behalf of a ClientPersistentFieldStorageImpl. Some effort is made to ensure that we don't uncessarily convert between objects and Base64 (the encoding used to record the value on the client).
 
 {
     static final String PARAMETER_NAME = "t:state:client";
 
     private static class Key implements Serializable
     {
         private static final long serialVersionUID = -2741540370081645945L;
 
         private final String pageName;
 
         private final String componentId;
 
         private final String fieldName;
 
         Key(String pageNameString componentIdString fieldName)
         {
             this. = pageName;
             this. = componentId;
             this. = fieldName;
         }
 
         public boolean matches(String pageName)
         {
             return this..equals(pageName);
         }
 
         public PersistentFieldChange toChange(Object value)
         {
             return new PersistentFieldChangeImpl( == null ? "" : ,
                                                  value);
         }
 
         @Override
         public int hashCode()
         {
             final int PRIME = 31;
 
             int result = 1;
 
             result = PRIME * result + (( == null) ? 0 : .hashCode());
 
             // fieldName and pageName are never null
 
             result = PRIME * result + .hashCode();
             result = PRIME * result + .hashCode();
 
             return result;
         }
 
         @Override
         public boolean equals(Object obj)
         {
             if (this == objreturn true;
             if (obj == nullreturn false;
             if (getClass() != obj.getClass()) return false;
             final Key other = (Keyobj;
 
             // fieldName and pageName are never null
 
             if (!.equals(other.fieldName)) return false;
            if (!.equals(other.pageName)) return false;
            if ( == null)
            {
                if (other.componentId != nullreturn false;
            }
            else if (!.equals(other.componentId)) return false;
            return true;
        }
    }
    private final ClientDataEncoder clientDataEncoder;
    private final Map<KeyObjectpersistedValues = CollectionFactory.newMap();
    private String clientData;
    private boolean mapUptoDate = false;
    public ClientPersistentFieldStorageImpl(Request requestClientDataEncoder clientDataEncoder)
    {
        this. = clientDataEncoder;
        // This, here, is the problem of TAPESTRY-2501; this call can predate
        // the check to set the character set based on meta data of the page.
        String value = request.getParameter();
        // MIME can encode to a '+' character; the browser converts that to a space; we convert it
        // back.
         = value == null ? null : value.replace(' ''+');
    }
    public void updateLink(Link link)
    {
        refreshClientData();
        if ( != nulllink.addParameter();
    }
    {
        refreshMap();
        if (.isEmpty()) return Collections.emptyList();
        Collection<PersistentFieldChangeresult = CollectionFactory.newList();
        for (Map.Entry<KeyObjecte : .entrySet())
        {
            Key key = e.getKey();
            if (key.matches(pageName)) result.add(key.toChange(e.getValue()));
        }
        return result;
    }
    public void discardChanges(String pageName)
    {
        refreshMap();
        Collection<KeyremovedKeys = CollectionFactory.newList();
        for (Key key : .keySet())
        {
            if (key.pageName.equals(pageName)) removedKeys.add(key);
        }
        for (Key key : removedKeys)
        {
            .remove(key);
             = null;
        }
    }
    public void postChange(String pageNameString componentIdString fieldNameObject newValue)
    {
        refreshMap();
        Key key = new Key(pageNamecomponentIdfieldName);
        if (newValue == null)
            .remove(key);
        else
        {
            if (!Serializable.class.isInstance(newValue))
                throw new IllegalArgumentException(ServicesMessages
                        .clientStateMustBeSerializable(newValue));
            .put(keynewValue);
        }
         = null;
    }

    
Refreshes the _persistedValues map if it is not up to date.
    @SuppressWarnings("unchecked")
    private void refreshMap()
    {
        if (return;
        // Parse the client data to form the map.
        restoreMapFromClientData();
         = true;
    }

    
Restores the _persistedValues map from the client data provided in the incoming Request.
    private void restoreMapFromClientData()
    {
        .clear();
        if ( == nullreturn;
        ObjectInputStream in = null;
        try
        {
            in = .decodeClientData();
            int count = in.readInt();
            for (int i = 0; i < counti++)
            {
                Key key = (Keyin.readObject();
                Object value = in.readObject();
                .put(keyvalue);
            }
        }
        catch (Exception ex)
        {
            throw new RuntimeException(ServicesMessages.corruptClientState(), ex);
        }
        finally
        {
            InternalUtils.close(in);
        }
    }
    private void refreshClientData()
    {
        // Client data will be null after a change to the map, or if there was no client data in the
        // request. In any other case where the client data is non-null, it is by definition
        // up-to date (since it is reset to null any time there's a change to the map).
        if ( != nullreturn;
        // Very typical: we're refreshing the client data but haven't created the map yet, and there
        // was no value in the request. Leave it as null.
        if (!return;
        // Null is also appropriate when the persisted values are empty.
        if (.isEmpty()) return;
        // Otherwise, time to update clientData from persistedValues
        ClientDataSink sink = .createSink();
        ObjectOutputStream os = sink.getObjectOutputStream();
        try
        {
            os.writeInt(.size());
            for (Map.Entry<KeyObjecte : .entrySet())
            {
                os.writeObject(e.getKey());
                os.writeObject(e.getValue());
            }
        }
        catch (Exception ex)
        {
            throw new RuntimeException(ex.getMessage(), ex);
        }
        finally
        {
            InternalUtils.close(os);
        }
         = sink.getClientData();
    }
New to GrepCode? Check out our FAQ X