001    // Copyright 2008, 2009, 2010 The Apache Software Foundation
002    //
003    // Licensed under the Apache License, Version 2.0 (the "License");
004    // you may not use this file except in compliance with the License.
005    // You may obtain a copy of the License at
006    //
007    // http://www.apache.org/licenses/LICENSE-2.0
008    //
009    // Unless required by applicable law or agreed to in writing, software
010    // distributed under the License is distributed on an "AS IS" BASIS,
011    // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012    // See the License for the specific language governing permissions and
013    // limitations under the License.
014    
015    package org.apache.tapestry5.corelib.internal;
016    
017    import java.io.IOException;
018    import java.io.ObjectOutputStream;
019    
020    import org.apache.tapestry5.ComponentAction;
021    import org.apache.tapestry5.runtime.Component;
022    import org.apache.tapestry5.services.ClientDataEncoder;
023    import org.apache.tapestry5.services.ClientDataSink;
024    import org.slf4j.Logger;
025    
026    /**
027     * Used to collection component actions, with the ultimate goal being the creation of a MIME-encoded string of the
028     * serialization of those actions.
029     */
030    public class ComponentActionSink
031    {
032        private final Logger logger;
033    
034        private final ObjectOutputStream stream;
035    
036        private final ClientDataSink sink;
037    
038        private boolean empty = true;
039    
040        public ComponentActionSink(Logger logger, ClientDataEncoder encoder)
041        {
042            this.logger = logger;
043    
044            sink = encoder.createSink();
045    
046            stream = sink.getObjectOutputStream();
047        }
048    
049        public <T> void store(T component, ComponentAction<T> action)
050        {
051            Component castComponent = (Component) component;
052            assert action != null;
053    
054            String completeId = castComponent.getComponentResources().getCompleteId();
055    
056            logger.debug("Storing action: {} {}", completeId, action);
057    
058            try
059            {
060                // Writing the complete id is not very efficient, but the GZip filter
061                // should help out there.
062                stream.writeUTF(completeId);
063                stream.writeObject(action);
064            }
065            catch (IOException ex)
066            {
067                throw new RuntimeException(InternalMessages.componentActionNotSerializable(completeId, ex), ex);
068            }
069    
070            empty = false;
071        }
072    
073        /** @since 5.2.0 */
074        public boolean isEmpty()
075        {
076            return empty;
077        }
078    
079        public String getClientData()
080        {
081            return sink.getClientData();
082        }
083    }