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
015package org.apache.tapestry5.corelib.internal;
016
017import java.io.IOException;
018import java.io.ObjectOutputStream;
019
020import org.apache.tapestry5.ComponentAction;
021import org.apache.tapestry5.runtime.Component;
022import org.apache.tapestry5.services.ClientDataEncoder;
023import org.apache.tapestry5.services.ClientDataSink;
024import 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 */
030public 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}