00001 /** 00002 Licensed to the Apache Software Foundation (ASF) under one 00003 or more contributor license agreements. See the NOTICE file 00004 distributed with this work for additional information 00005 regarding copyright ownership. The ASF licenses this file 00006 to you under the Apache License, Version 2.0 (the 00007 "License"); you may not use this file except in compliance 00008 with the License. You may obtain a copy of the License at 00009 00010 http://www.apache.org/licenses/LICENSE-2.0 00011 00012 Unless required by applicable law or agreed to in writing, software 00013 distributed under the License is distributed on an "AS IS" BASIS, 00014 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00015 See the License for the specific language governing permissions and 00016 limitations under the License. 00017 */ 00018 00019 /** 00020 * @file TransformationPlugin.h 00021 */ 00022 00023 #pragma once 00024 #ifndef ATSCPPAPI_TRANSFORMATIONPLUGIN_H_ 00025 #define ATSCPPAPI_TRANSFORMATIONPLUGIN_H_ 00026 00027 #include <string> 00028 #include <atscppapi/Transaction.h> 00029 #include <atscppapi/TransactionPlugin.h> 00030 00031 namespace atscppapi { 00032 00033 struct TransformationPluginState; 00034 00035 /** 00036 * @brief The interface used when you wish to transform Request or Response body content. 00037 * 00038 * Transformations are deceptively simple, transformations are chained so the output 00039 * of one TransformationPlugin becomes the input of another TransformationPlugin. As 00040 * data arrives it will fire a consume() and when all the data has been sent 00041 * you will receive a handleInputComplete(). Data can be sent to the next TransformationPlugin 00042 * in the chain by calling produce() and when the transformation has no data left to send 00043 * it will fire a setOutputCompete(). 00044 * 00045 * Since a TransformationPlugin is a type of TransactionPlugin you can call registerHook() and 00046 * establish any hook for a Transaction also; however, remember that you must implement 00047 * the appropriate callback for any hooks you register. 00048 * 00049 * A simple example of how to use the TransformationPlugin interface follows, this is an example 00050 * of a Response transformation, the avialable options are REQUEST_TRANSFORMATION and RESPONSE_TRANSFORMATION 00051 * which are defined in Type. 00052 * 00053 * This example is a Null Transformation, meaning it will just spit out the content it receives without 00054 * actually doing any work on it. 00055 * 00056 * \code 00057 * class NullTransformationPlugin : public TransformationPlugin { 00058 * public: 00059 * NullTransformationPlugin(Transaction &transaction) 00060 * : TransformationPlugin(transaction, RESPONSE_TRANSFORMATION) { 00061 * registerHook(HOOK_SEND_RESPONSE_HEADERS); 00062 * } 00063 * void handleSendResponseHeaders(Transaction &transaction) { 00064 * transaction.getClientResponse().getHeaders().set("X-Content-Transformed", "1"); 00065 * transaction.resume(); 00066 * } 00067 * void consume(const string &data) { 00068 * produce(data); 00069 * } 00070 * void handleInputComplete() { 00071 * setOutputComplete(); 00072 * } 00073 * }; 00074 * \endcode 00075 * 00076 * @see Plugin 00077 * @see TransactionPlugin 00078 * @see Type 00079 * @see HookType 00080 */ 00081 class TransformationPlugin : public TransactionPlugin { 00082 public: 00083 /** 00084 * The available types of Transformations. 00085 */ 00086 enum Type { 00087 REQUEST_TRANSFORMATION = 0, /**< Transform the Request body content */ 00088 RESPONSE_TRANSFORMATION /**< Transform the Response body content */ 00089 }; 00090 00091 /** 00092 * A method that you must implement when writing a TransformationPlugin, this method will be 00093 * fired whenever an upstream TransformationPlugin has produced output. 00094 */ 00095 virtual void consume(const std::string &data) = 0; 00096 00097 /** 00098 * A method that you must implement when writing a TransformationPlugin, this method 00099 * will be fired whenever the upstream TransformationPlugin has completed writing data. 00100 */ 00101 virtual void handleInputComplete() = 0; 00102 00103 virtual ~TransformationPlugin(); /**< Destructor for a TransformationPlugin */ 00104 protected: 00105 00106 /** 00107 * This method is how a TransformationPlugin will produce output for the downstream 00108 * transformation plugin, if you need to produce binary data this can still be 00109 * done with strings by a call to string::assign() or by constructing a string 00110 * with string::string(char *, size_t). 00111 */ 00112 size_t produce(const std::string &); 00113 00114 /** 00115 * This is the method that you must call when you're done producing output for 00116 * the downstream TranformationPlugin. 00117 */ 00118 size_t setOutputComplete(); 00119 00120 /** a TransformationPlugin must implement this interface, it cannot be constructed directly */ 00121 TransformationPlugin(Transaction &transaction, Type type); 00122 private: 00123 TransformationPluginState *state_; /** Internal state for a TransformationPlugin */ 00124 size_t doProduce(const std::string &); 00125 }; 00126 00127 } /* atscppapi */ 00128 00129 00130 #endif /* ATSCPPAPI_TRANSFORMATIONPLUGIN_H_ */