reSIProcate/repro  9694
ProcessorChain.cxx
Go to the documentation of this file.
00001 #if defined(HAVE_CONFIG_H)
00002 #include "config.h"
00003 #endif
00004 
00005 #include <iostream>
00006 
00007 #include "repro/ProcessorChain.hxx"
00008 #include "resip/stack/SipMessage.hxx"
00009 #include "repro/ProcessorMessage.hxx"
00010 #include "repro/RequestContext.hxx"
00011 
00012 #include "rutil/Logger.hxx"
00013 #include "rutil/Inserter.hxx"
00014 
00015 #define RESIPROCATE_SUBSYSTEM resip::Subsystem::REPRO
00016 
00017 using namespace resip;
00018 using namespace repro;
00019 using namespace std;
00020 
00021 
00022 ProcessorChain::ProcessorChain(Processor::ChainType type) : 
00023    Processor(Data::Empty, type)
00024 {
00025    switch(type)
00026    {
00027    case REQUEST_CHAIN:
00028       setName("RequestProcessor");
00029       break;
00030    case RESPONSE_CHAIN:
00031       setName("ResponseProcessor");
00032       break;
00033    case TARGET_CHAIN:
00034       setName("TargetProcessor");
00035       break;
00036    case NO_TYPE:
00037    default:
00038       setName("UnknownProcessor");
00039       break;
00040    }
00041    DebugLog(<< "Instantiating new " << mName << " chain");
00042 }
00043 
00044 repro::ProcessorChain::~ProcessorChain()
00045 {
00046    //DebugLog (<< "Deleting Chain: " << this);
00047    for (Chain::iterator i = mChain.begin(); i != mChain.end(); ++i)
00048    {
00049       //DebugLog (<< "Deleting RP: " << *i << " : " << **i);
00050       delete *i;
00051    }
00052    mChain.clear();
00053 }
00054 
00055 void
00056 repro::ProcessorChain::addProcessor(auto_ptr<Processor> rp)
00057 {
00058    DebugLog(<< "Adding new " << mName << " to chain: " << *(rp.get()));
00059    rp->pushAddress((short)mChain.size());
00060    rp->pushAddress(mAddress);
00061    rp->setChainType(mType);
00062    mChain.push_back(rp.release());
00063 }
00064 
00065 repro::Processor::processor_action_t
00066 repro::ProcessorChain::process(RequestContext &rc)
00067 {
00068    //DebugLog(<< mName << " handling request: " << *this << "; reqcontext = " << rc);
00069 
00070    processor_action_t action;
00071    unsigned int position=0;
00072 
00073    resip::Message* msg = rc.getCurrentEvent();
00074 
00075    if(msg)
00076    {
00077       ProcessorMessage* proc = dynamic_cast<ProcessorMessage*>(msg);
00078       
00079       if(proc)
00080       {
00081          position=proc->popAddr();
00082       }
00083    }
00084    
00085    for (; (position >=0 && position < mChain.size()); ++position)
00086    {
00087       DebugLog(<< "Chain invoking " << mName << ": " << *(mChain[position]));
00088 
00089       action = mChain[position]->process(rc);
00090 
00091       if (action == SkipAllChains)
00092       {
00093          DebugLog(<< mName << " aborted all chains: " << *(mChain[position]));
00094          return SkipAllChains;
00095       }
00096 
00097       if (action == WaitingForEvent)
00098       {
00099          DebugLog(<< mName << " waiting for async response: " << *(mChain[position]));
00100          return WaitingForEvent;
00101       }
00102 
00103       if (action == SkipThisChain)
00104       {
00105          DebugLog(<< mName << " skipping current chain: " << *(mChain[position]));
00106          return Continue;
00107       }
00108 
00109    }
00110    //DebugLog(<< "Monkey done processing: " << *(mChain[position]));
00111    return Continue;
00112 }
00113 
00114 void
00115 ProcessorChain::pushAddress(const std::vector<short>& address)
00116 {
00117    Processor::pushAddress(address);
00118    for(std::vector<Processor*>::iterator i=mChain.begin();i!=mChain.end();++i)
00119    {
00120       (**i).pushAddress(address);
00121    }
00122 }
00123 
00124 void
00125 ProcessorChain::pushAddress(const short address)
00126 {
00127    Processor::pushAddress(address);
00128    for(std::vector<Processor*>::iterator i=mChain.begin();i!=mChain.end();++i)
00129    {
00130       (**i).pushAddress(address);
00131    }   
00132 }
00133 
00134 
00135 void
00136 ProcessorChain::setChainType(ChainType type)
00137 {
00138    mType=type;
00139    std::vector<Processor*>::iterator i;
00140    for(i=mChain.begin();i!=mChain.end();++i)
00141    {
00142       (*i)->setChainType(type);
00143    }
00144 }
00145 
00146 EncodeStream &
00147 repro::operator << (EncodeStream &os, const repro::ProcessorChain &pc)
00148 {
00149    os << pc.getName() << " chain: " << InserterP(pc.mChain);
00150    return os;
00151 }
00152 
00153 
00154 /* ====================================================================
00155  * The Vovida Software License, Version 1.0 
00156  * 
00157  * Copyright (c) 2000 Vovida Networks, Inc.  All rights reserved.
00158  * 
00159  * Redistribution and use in source and binary forms, with or without
00160  * modification, are permitted provided that the following conditions
00161  * are met:
00162  * 
00163  * 1. Redistributions of source code must retain the above copyright
00164  *    notice, this list of conditions and the following disclaimer.
00165  * 
00166  * 2. Redistributions in binary form must reproduce the above copyright
00167  *    notice, this list of conditions and the following disclaimer in
00168  *    the documentation and/or other materials provided with the
00169  *    distribution.
00170  * 
00171  * 3. The names "VOCAL", "Vovida Open Communication Application Library",
00172  *    and "Vovida Open Communication Application Library (VOCAL)" must
00173  *    not be used to endorse or promote products derived from this
00174  *    software without prior written permission. For written
00175  *    permission, please contact vocal@vovida.org.
00176  *
00177  * 4. Products derived from this software may not be called "VOCAL", nor
00178  *    may "VOCAL" appear in their name, without prior written
00179  *    permission of Vovida Networks, Inc.
00180  * 
00181  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
00182  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00183  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
00184  * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL VOVIDA
00185  * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
00186  * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
00187  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00188  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00189  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
00190  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00191  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
00192  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
00193  * DAMAGE.
00194  * 
00195  * ====================================================================
00196  * 
00197  * This software consists of voluntary contributions made by Vovida
00198  * Networks, Inc. and many individuals on behalf of Vovida Networks,
00199  * Inc.  For more information on Vovida Networks, Inc., please see
00200  * <http://www.vovida.org/>.
00201  *
00202  */