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 }