    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    }