Salome HOME
Update copyrights 2014.
[samples/hello.git] / src / HELLO / HELLO.cxx
1 // Copyright (C) 2007-2014  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 <SALOMEconfig.h>
27 #include CORBA_CLIENT_HEADER(SALOMEDS)
28 #include CORBA_CLIENT_HEADER(SALOMEDS_Attributes)
29
30 #include <Utils_ExceptHandlers.hxx>
31
32 #include <string>
33
34 namespace {
35   static std::string studyName( const std::string& name )
36   {
37     std::string fullName = "/Hello/";
38     fullName += name;
39     return fullName;
40   }
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::HELLO( CORBA::ORB_ptr orb,
55               PortableServer::POA_ptr poa,
56               PortableServer::ObjectId* contId, 
57               const char* instanceName, 
58               const char* interfaceName )
59   : Engines_Component_i( orb, poa, contId, instanceName, interfaceName )
60 {
61   _thisObj = this;
62   _id = _poa->activate_object( _thisObj ); // register and activate this servant object
63 }
64
65 /*!
66   \brief Destructor
67
68   Clean up allocated resources
69 */
70 HELLO::~HELLO()
71 {
72   // nothing to do
73 }
74
75 /*!
76   \brief Say hello to \a name
77   \param study SALOME study
78   \param name person's name
79   \return operation status
80 */
81 HELLO_ORB::status HELLO::hello( SALOMEDS::Study_ptr study, 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   // check if reference to study is valid
90   if ( !CORBA::is_nil( study ) ) {
91     // get full object path
92     std::string fullName = studyName( name );
93     // check if the object with the same name is already registered in the study
94     SALOMEDS::SObject_var sobj = study->FindObjectByPath( fullName.c_str() );
95     if ( !CORBA::is_nil( sobj ) ) {
96       // person is already registered in the study -> ERROR
97       result = HELLO_ORB::OP_ERR_ALREADY_MET;
98     }
99     else {
100       // person is not registered yet -> register
101       SALOMEDS::StudyBuilder_var     studyBuilder   = study->NewBuilder();          // study builder
102       SALOMEDS::UseCaseBuilder_var   useCaseBuilder = study->GetUseCaseBuilder();   // use case builder
103
104       // find HELLO component; create it if not found
105       SALOMEDS::SComponent_var father = study->FindComponent( "HELLO" );
106       if ( CORBA::is_nil( father ) ) {
107         // create component
108         father = studyBuilder->NewComponent( "HELLO" ); 
109         // set name attribute
110         father->SetAttrString( "AttributeName", "Hello" );
111         // set icon attribute
112         father->SetAttrString( "AttributePixMap", "ICON_HELLO" );
113         // register component in the study
114         studyBuilder->DefineComponentInstance( father, HELLO_Gen::_this() );
115         // add component to the use case tree
116         // (to support tree representation customization and drag-n-drop)
117         useCaseBuilder->SetRootCurrent();
118         useCaseBuilder->Append( father ); // component object is added as the top level item
119       }
120
121       // create new sub-object, as a child of the component object
122       sobj = studyBuilder->NewObject( father );
123       sobj->SetAttrString( "AttributeName", name );
124       // add object to the use case tree
125       // (to support tree representation customization and drag-n-drop)
126       useCaseBuilder->AppendTo( father, sobj );
127
128       // cleanup
129       father->UnRegister();
130       sobj->UnRegister();
131
132       // set operation status
133       result = HELLO_ORB::OP_OK;
134     }
135   }
136   
137   // return result of the operation
138   return result;
139 }
140
141 /*!
142   \brief Say goodbye to \a name
143   \param study SALOME study
144   \param name person's name
145   \return operation status
146 */
147 HELLO_ORB::status HELLO::goodbye( SALOMEDS::Study_ptr study, 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   // check if reference to study is valid
156   if ( !CORBA::is_nil( study ) ) {
157     // get full object path
158     std::string fullName = studyName( name );
159
160     // initially set error status: person is not registered
161     result = HELLO_ORB::OP_ERR_DID_NOT_MEET;
162
163     // check if the object with the same name is registered in the study
164     // find all objects with same name
165     SALOMEDS::StudyBuilder_var studyBuilder = study->NewBuilder();            // study builder
166     SALOMEDS::UseCaseBuilder_var useCaseBuilder = study->GetUseCaseBuilder(); // use case builder
167     SALOMEDS::SObject_var sobj = study->FindObjectByPath( fullName.c_str() );
168     while ( !CORBA::is_nil( sobj ) ) {
169       std::list<SALOMEDS::SObject_var> toRemove;
170       toRemove.push_back( sobj );
171       SALOMEDS::UseCaseIterator_var useCaseIt = useCaseBuilder->GetUseCaseIterator( sobj ); // use case iterator
172       for ( useCaseIt->Init( true ); useCaseIt->More(); useCaseIt->Next() )
173         toRemove.push_back( useCaseIt->Value() );
174       // perform removing of all found objects (recursively with children)
175       std::list<SALOMEDS::SObject_var>::const_iterator it;
176       for( it = toRemove.begin(); it != toRemove.end(); ++it ) {
177         sobj = *it;
178         // remove object from the study
179         // - normally it's enough to call RemoveObject() method
180         // RemoveObject`WithChildren() also removes all children recursively if there are any
181         // - it's not necessary to remove it from use case builder, it is done automatically
182         studyBuilder->RemoveObjectWithChildren( sobj );
183         
184         // cleanup
185         sobj->UnRegister();
186         
187         // set operation status to OK as at least one object is removed
188         result = HELLO_ORB::OP_OK;
189       }
190       sobj = study->FindObjectByPath( fullName.c_str() );
191     }
192   }
193   
194   // return result of the operation
195   return result;
196 }
197
198 /*!
199   \brief Copy or move objects to the specified position
200   
201   This function is used in the drag-n-drop functionality.
202   
203   \param what objects being copied/moved
204   \param where parent object where objects are copied/moved to
205   \param row position in the parent object's children list at which objects are copied/moved
206   \param isCopy \c true if object are copied or \c false otherwise
207 */
208 void HELLO::copyOrMove( const HELLO_ORB::object_list& what,
209                         SALOMEDS::SObject_ptr where,
210                         CORBA::Long row, CORBA::Boolean isCopy )
211 {
212   if ( CORBA::is_nil( where ) ) return; // bad parent
213
214   SALOMEDS::Study_var study = where->GetStudy();                               // study
215   SALOMEDS::StudyBuilder_var studyBuilder = study->NewBuilder();               // study builder
216   SALOMEDS::UseCaseBuilder_var useCaseBuilder = study->GetUseCaseBuilder();    // use case builder
217   SALOMEDS::SComponent_var father = where->GetFatherComponent();               // father component
218   std::string dataType = father->ComponentDataType();
219   if ( dataType != "HELLO" ) return; // not a HELLO component
220   
221   SALOMEDS::SObject_var objAfter;
222   if ( row >= 0 && useCaseBuilder->HasChildren( where ) ) {
223     // insert at given row -> find insertion position
224     SALOMEDS::UseCaseIterator_var useCaseIt = useCaseBuilder->GetUseCaseIterator( where );
225     int i;
226     for ( i = 0; i < row && useCaseIt->More(); i++, useCaseIt->Next() );
227     if ( i == row && useCaseIt->More() ) {
228       objAfter = useCaseIt->Value();
229     }
230   }
231   
232   for ( int i = 0; i < what.length(); i++ ) {
233     SALOMEDS::SObject_var sobj = what[i];
234     if ( CORBA::is_nil( sobj ) ) continue; // skip bad object
235     if ( isCopy ) {
236       // copying is performed
237       // get name of the object
238       CORBA::String_var name = sobj->GetName();
239       // create new object, as a child of the component object
240       SALOMEDS::SObject_var new_sobj = studyBuilder->NewObject( father );
241       new_sobj->SetAttrString( "AttributeName", name.in() );
242       sobj = new_sobj;
243     }
244     // insert the object or its copy to the use case tree
245     if ( !CORBA::is_nil( objAfter ) )
246       useCaseBuilder->InsertBefore( sobj, objAfter ); // insert at given row
247     else
248       useCaseBuilder->AppendTo( where, sobj );        // append to the end of list
249   }
250 }
251
252 // Version information
253 char* HELLO::getVersion()
254 {
255 #if defined(HELLO_DEVELOPMENT)
256   return CORBA::string_dup(HELLO_VERSION_STR"dev");
257 #else
258   return CORBA::string_dup(HELLO_VERSION_STR);
259 #endif
260 }
261
262 extern "C"
263 {
264   /*!
265     \brief Exportable factory function: create an instance of the HELLO component engine
266     \param orb reference to the ORB
267     \param poa reference to the POA
268     \param contId CORBA object ID, pointing to the owner SALOME container
269     \param instanceName SALOME component instance name
270     \param interfaceName SALOME component interface name
271     \return CORBA object identifier of the registered servant
272   */
273   PortableServer::ObjectId* HELLOEngine_factory( CORBA::ORB_ptr orb,
274                                                  PortableServer::POA_ptr poa, 
275                                                  PortableServer::ObjectId* contId,
276                                                  const char* instanceName, 
277                                                  const char* interfaceName )
278   {
279     HELLO* component = new HELLO( orb, poa, contId, instanceName, interfaceName );
280     return component->getId();
281   }
282 }