Salome HOME
709f40f8e9f981f762c8aa637d253ea2550a25c1
[samples/hello.git] / src / HELLO / HELLO.cxx
1 // Copyright (C) 2007-2021  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 #include "HELLO.hxx"
24 #include "HELLO_version.h"
25
26 #include <SALOME_KernelServices.hxx>
27 #include <SALOMEconfig.h>
28 #include CORBA_CLIENT_HEADER(SALOMEDS)
29 #include CORBA_CLIENT_HEADER(SALOMEDS_Attributes)
30
31 #include <Utils_ExceptHandlers.hxx>
32
33 #include <string>
34
35 namespace {
36   static std::string studyName( const std::string& name )
37   {
38     std::string fullName = "/Hello/";
39     fullName += name;
40     return fullName;
41   }
42 }
43 /*!
44   \brief Constructor
45
46   Creates an instance of the HELLO component engine
47   
48   \param orb reference to the ORB
49   \param poa reference to the POA
50   \param contId CORBA object ID, pointing to the owner SALOME container
51   \param instanceName SALOME component instance name
52   \param interfaceName SALOME component interface name
53 */
54 HELLO_Abstract::HELLO_Abstract( CORBA::ORB_ptr orb,
55               PortableServer::POA_ptr poa,
56               PortableServer::ObjectId* contId, 
57               const char* instanceName, 
58               const char* interfaceName,
59         bool withRegistry)
60   : Engines_Component_i( orb, poa, contId, instanceName, interfaceName, false, withRegistry)
61 {
62   _thisObj = this;
63   _id = _poa->activate_object( _thisObj ); // register and activate this servant object
64 }
65
66 /*!
67   \brief Destructor
68
69   Clean up allocated resources
70 */
71 HELLO_Abstract::~HELLO_Abstract()
72 {
73   // nothing to do
74 }
75
76 /*!
77   \brief Say hello to \a name
78   \param name person's name
79   \return operation status
80 */
81 HELLO_ORB::status HELLO_Abstract::hello( const char* name )
82 {
83   // set exception handler to catch unexpected CORBA exceptions
84   Unexpect aCatch(SALOME_SalomeException);
85   
86   // set result status to error initially
87   HELLO_ORB::status result = HELLO_ORB::OP_ERR_UNKNOWN;
88
89   SALOMEDS::Study_var aStudy = this->getStudyServant();
90   // check if reference to study is valid
91   if ( !CORBA::is_nil( aStudy ) ) {
92     // get full object path
93     std::string fullName = studyName( name );
94     // check if the object with the same name is already registered in the study
95     SALOMEDS::SObject_var sobj = aStudy->FindObjectByPath( fullName.c_str() );
96     if ( !CORBA::is_nil( sobj ) ) {
97       // person is already registered in the study -> ERROR
98       result = HELLO_ORB::OP_ERR_ALREADY_MET;
99     }
100     else {
101       // person is not registered yet -> register
102       SALOMEDS::StudyBuilder_var     studyBuilder   = aStudy->NewBuilder();          // study builder
103       SALOMEDS::UseCaseBuilder_var   useCaseBuilder = aStudy->GetUseCaseBuilder();   // use case builder
104
105       // find HELLO component; create it if not found
106       SALOMEDS::SComponent_var father = aStudy->FindComponent( "HELLO" );
107       if ( CORBA::is_nil( father ) ) {
108         // create component
109         father = studyBuilder->NewComponent( "HELLO" ); 
110         // set name attribute
111         father->SetAttrString( "AttributeName", "Hello" );
112         // set icon attribute
113         father->SetAttrString( "AttributePixMap", "ICON_HELLO" );
114         // register component in the study
115         studyBuilder->DefineComponentInstance( father, HELLO_Gen::_this() );
116         // add component to the use case tree
117         // (to support tree representation customization and drag-n-drop)
118         useCaseBuilder->SetRootCurrent();
119         useCaseBuilder->Append( father ); // component object is added as the top level item
120       }
121
122       // create new sub-object, as a child of the component object
123       sobj = studyBuilder->NewObject( father );
124       sobj->SetAttrString( "AttributeName", name );
125       // add object to the use case tree
126       // (to support tree representation customization and drag-n-drop)
127       useCaseBuilder->AppendTo( father, sobj );
128
129       // cleanup
130       father->UnRegister();
131       sobj->UnRegister();
132
133       // set operation status
134       result = HELLO_ORB::OP_OK;
135     }
136   }
137   
138   // return result of the operation
139   return result;
140 }
141
142 /*!
143   \brief Say goodbye to \a name
144   \param name person's name
145   \return operation status
146 */
147 HELLO_ORB::status HELLO_Abstract::goodbye( const char* name )
148 {
149   // set exception handler to catch unexpected CORBA exceptions
150   Unexpect aCatch(SALOME_SalomeException);
151   
152   // set result status to error initially
153   HELLO_ORB::status result = HELLO_ORB::OP_ERR_UNKNOWN;
154
155   SALOMEDS::Study_var aStudy = this->getStudyServant();
156   // check if reference to study is valid
157   if ( !CORBA::is_nil( aStudy ) ) {
158     // get full object path
159     std::string fullName = studyName( name );
160
161     // initially set error status: person is not registered
162     result = HELLO_ORB::OP_ERR_DID_NOT_MEET;
163
164     // check if the object with the same name is registered in the study
165     // find all objects with same name
166     SALOMEDS::StudyBuilder_var studyBuilder = aStudy->NewBuilder();            // study builder
167     SALOMEDS::UseCaseBuilder_var useCaseBuilder = aStudy->GetUseCaseBuilder(); // use case builder
168     SALOMEDS::SObject_var sobj = aStudy->FindObjectByPath( fullName.c_str() );
169     while ( !CORBA::is_nil( sobj ) ) {
170       std::list<SALOMEDS::SObject_var> toRemove;
171       toRemove.push_back( sobj );
172       SALOMEDS::UseCaseIterator_var useCaseIt = useCaseBuilder->GetUseCaseIterator( sobj ); // use case iterator
173       for ( useCaseIt->Init( true ); useCaseIt->More(); useCaseIt->Next() )
174         toRemove.push_back( useCaseIt->Value() );
175       // perform removing of all found objects (recursively with children)
176       std::list<SALOMEDS::SObject_var>::const_iterator it;
177       for( it = toRemove.begin(); it != toRemove.end(); ++it ) {
178         sobj = *it;
179         // remove object from the study
180         // - normally it's enough to call RemoveObject() method
181         // RemoveObject`WithChildren() also removes all children recursively if there are any
182         // - it's not necessary to remove it from use case builder, it is done automatically
183         studyBuilder->RemoveObjectWithChildren( sobj );
184         
185         // cleanup
186         sobj->UnRegister();
187         
188         // set operation status to OK as at least one object is removed
189         result = HELLO_ORB::OP_OK;
190       }
191       sobj = aStudy->FindObjectByPath( fullName.c_str() );
192     }
193   }
194   
195   // return result of the operation
196   return result;
197 }
198
199 /*!
200   \brief Copy or move objects to the specified position
201   
202   This function is used in the drag-n-drop functionality.
203   
204   \param what objects being copied/moved
205   \param where parent object where objects are copied/moved to
206   \param row position in the parent object's children list at which objects are copied/moved
207   \param isCopy \c true if object are copied or \c false otherwise
208 */
209 void HELLO_Abstract::copyOrMove( const HELLO_ORB::object_list& what,
210                         SALOMEDS::SObject_ptr where,
211                         CORBA::Long row, CORBA::Boolean isCopy )
212 {
213   if ( CORBA::is_nil( where ) ) return; // bad parent
214
215   SALOMEDS::Study_var aStudy = this->getStudyServant();
216   SALOMEDS::StudyBuilder_var studyBuilder = aStudy->NewBuilder();               // study builder
217   SALOMEDS::UseCaseBuilder_var useCaseBuilder = aStudy->GetUseCaseBuilder();    // use case builder
218   SALOMEDS::SComponent_var father = where->GetFatherComponent();               // father component
219   std::string dataType = father->ComponentDataType();
220   if ( dataType != "HELLO" ) return; // not a HELLO component
221   
222   SALOMEDS::SObject_var objAfter;
223   if ( row >= 0 && useCaseBuilder->HasChildren( where ) ) {
224     // insert at given row -> find insertion position
225     SALOMEDS::UseCaseIterator_var useCaseIt = useCaseBuilder->GetUseCaseIterator( where );
226     int i;
227     for ( i = 0; i < row && useCaseIt->More(); i++, useCaseIt->Next() );
228     if ( i == row && useCaseIt->More() ) {
229       objAfter = useCaseIt->Value();
230     }
231   }
232   
233   for ( int i = 0; i < what.length(); i++ ) {
234     SALOMEDS::SObject_var sobj = what[i];
235     if ( CORBA::is_nil( sobj ) ) continue; // skip bad object
236     if ( isCopy ) {
237       // copying is performed
238       // get name of the object
239       CORBA::String_var name = sobj->GetName();
240       // create new object, as a child of the component object
241       SALOMEDS::SObject_var new_sobj = studyBuilder->NewObject( father );
242       new_sobj->SetAttrString( "AttributeName", name.in() );
243       sobj = new_sobj;
244     }
245     // insert the object or its copy to the use case tree
246     if ( !CORBA::is_nil( objAfter ) )
247       useCaseBuilder->InsertBefore( sobj, objAfter ); // insert at given row
248     else
249       useCaseBuilder->AppendTo( where, sobj );        // append to the end of list
250   }
251 }
252
253 // Version information
254 char* HELLO_Abstract::getVersion()
255 {
256 #if defined(HELLO_DEVELOPMENT)
257   return CORBA::string_dup(HELLO_VERSION_STR"dev");
258 #else
259   return CORBA::string_dup(HELLO_VERSION_STR);
260 #endif
261 }
262
263 SALOMEDS::Study_var HELLO_Session::getStudyServant()
264 {
265   return KERNEL::getStudyServant();
266 }
267
268 #include "SALOMEDS_Study_i.hxx"
269
270 SALOMEDS::Study_var HELLO_No_Session::getStudyServant()
271 {
272   return SALOMEDS::Study::_duplicate(KERNEL::getStudyServantSA());
273 }
274
275 extern "C"
276 {
277   /*!
278     \brief Exportable factory function: create an instance of the HELLO component engine
279     \param orb reference to the ORB
280     \param poa reference to the POA
281     \param contId CORBA object ID, pointing to the owner SALOME container
282     \param instanceName SALOME component instance name
283     \param interfaceName SALOME component interface name
284     \return CORBA object identifier of the registered servant
285   */
286   PortableServer::ObjectId* HELLOEngine_factory( CORBA::ORB_ptr orb,
287                                                  PortableServer::POA_ptr poa, 
288                                                  PortableServer::ObjectId* contId,
289                                                  const char* instanceName, 
290                                                  const char* interfaceName )
291   {
292     HELLO_Session* component = new HELLO_Session( orb, poa, contId, instanceName, interfaceName );
293     return component->getId();
294   }
295 }