00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "assocrules.h"
00014
00015
00016 #include <kdebug.h>
00017 #include <typeinfo>
00018
00019
00020 #include "uml.h"
00021 #include "umlview.h"
00022 #include "umlwidget.h"
00023 #include "umlobject.h"
00024 #include "associationwidgetlist.h"
00025 #include "associationwidget.h"
00026 #include "statewidget.h"
00027 #include "activitywidget.h"
00028 #include "forkjoinwidget.h"
00029
00030
00031 using namespace Uml;
00032
00033 AssocRules::AssocRules() {}
00034
00035 AssocRules::~AssocRules() {}
00036
00037 bool allowAssociation( Association_Type, const std::type_info )
00038 {
00039 return false;
00040
00041 }
00042
00043 bool AssocRules::allowAssociation( Association_Type assocType, UMLWidget * widget ) {
00044 Widget_Type widgetType = widget -> getBaseType();
00045 bool bValid = false;
00046 for (int i = 0; i < m_nNumRules; i++) {
00047 if (assocType == m_AssocRules[i].assoc_type) {
00048 if (widgetType == m_AssocRules[i].widgetA_type
00049 || widgetType == m_AssocRules[i].widgetB_type ) {
00050 bValid = true;
00051 }
00052 }
00053 }
00054 if( !bValid ) {
00055
00056 UMLView *view = UMLApp::app()->getCurrentView();
00057 if (view && view->getType() == dt_Component && widgetType == wt_Package &&
00058 (assocType == at_Generalization || assocType == at_Realization))
00059 bValid = true;
00060 else
00061 return false;
00062 }
00063 AssociationWidgetList list = widget -> getAssocList();
00064 AssociationWidgetListIt it( list );
00065 AssociationWidget * assoc = 0;
00066 switch( assocType ) {
00067 case at_Association:
00068 case at_UniAssociation:
00069 case at_Dependency:
00070 case at_Coll_Message:
00071 case at_Generalization:
00072 case at_Aggregation:
00073 case at_Relationship:
00074 case at_Composition:
00075 case at_Containment:
00076 return true;
00077 break;
00078
00079 case at_Association_Self:
00080 return true;
00081 break;
00082
00083 case at_Realization:
00084 while( ( assoc = it.current() ) ) {
00085 if( assoc -> getAssocType() == at_Realization )
00086 return false;
00087 ++it;
00088 }
00089 return true;
00090 break;
00091
00092 case at_State:
00093 {
00094 StateWidget *pState = dynamic_cast<StateWidget*>(widget);
00095 return (pState == NULL || pState->getStateType() != StateWidget::End);
00096 }
00097 break;
00098
00099 case at_Activity:
00100 {
00101 ActivityWidget *pActivity = dynamic_cast<ActivityWidget*>(widget);
00102 return (pActivity == NULL || pActivity->getActivityType() != ActivityWidget::End);
00103 }
00104 break;
00105
00106 case at_Anchor:
00107 return true;
00108 break;
00109 default:
00110 kWarning() << "allowAssociation() on unknown type" << endl;
00111 break;
00112 }
00113 return false;
00114 }
00115
00116
00117
00118 bool AssocRules::allowAssociation( Association_Type assocType,
00119 UMLWidget * widgetA, UMLWidget * widgetB,
00120 bool extendedCheck ) {
00121 Widget_Type widgetTypeA = widgetA->getBaseType();
00122 Widget_Type widgetTypeB = widgetB->getBaseType();
00123 bool bValid = false;
00124 for (int i = 0; i < m_nNumRules; i++) {
00125 if (assocType == m_AssocRules[i].assoc_type) {
00126 if( (widgetTypeA == m_AssocRules[i].widgetA_type &&
00127 widgetTypeB == m_AssocRules[i].widgetB_type) ||
00128 (widgetTypeB == m_AssocRules[i].widgetA_type &&
00129 widgetTypeA == m_AssocRules[i].widgetB_type ) )
00130 bValid = true;
00131 }
00132 }
00133
00134
00135 if (!extendedCheck) {
00136 return bValid;
00137 }
00138
00139 if (!bValid) {
00140 return false;
00141 }
00142 AssociationWidgetList list = widgetB -> getAssocList();
00143 AssociationWidgetListIt it( list );
00144 AssociationWidget * assoc = 0;
00145 switch( assocType ) {
00146 case at_Association:
00147 case at_Association_Self:
00148 case at_UniAssociation:
00149 case at_Dependency:
00150 case at_Coll_Message:
00151 case at_Aggregation:
00152 case at_Relationship:
00153 return true;
00154 break;
00155
00156 case at_Composition:
00157 case at_Containment:
00158 case at_Generalization:
00159 while( ( assoc = it.current() ) ) {
00160 if( ( widgetA == assoc -> getWidget(A) || widgetA == assoc -> getWidget(B) )
00161 && assoc->getAssocType() == assocType )
00162 return false;
00163 ++it;
00164 }
00165 return true;
00166 break;
00167
00168 case at_Realization:
00169 while( ( assoc = it.current() ) ) {
00170 if( ( widgetA == assoc->getWidget(A) || widgetA == assoc->getWidget(B) )
00171 && assoc->getAssocType() == at_Realization ) {
00172 return false;
00173 }
00174 ++it;
00175 }
00176 if (widgetB->getBaseType() == wt_Class) {
00177 return widgetB->getUMLObject()->getAbstract();
00178 } else if (widgetB->getBaseType() == wt_Interface ||
00179 widgetB->getBaseType() == wt_Package) {
00180 return true;
00181 }
00182 break;
00183
00184 case at_State:
00185 {
00186 StateWidget *stateA = dynamic_cast<StateWidget*>(widgetA);
00187 StateWidget *stateB = dynamic_cast<StateWidget*>(widgetB);
00188 if (stateA && stateB) {
00189 if (stateB->getStateType() == StateWidget::Initial)
00190 return false;
00191 if (stateB->getStateType() == StateWidget::End &&
00192 stateA->getStateType() != StateWidget::Normal)
00193 return false;
00194 }
00195 }
00196 return true;
00197 break;
00198
00199 case at_Activity:
00200 {
00201 ActivityWidget *actA = dynamic_cast<ActivityWidget*>(widgetA);
00202 ActivityWidget *actB = dynamic_cast<ActivityWidget*>(widgetB);
00203
00204 if (actB && actB->getActivityType() == ActivityWidget::Initial)
00205 return false;
00206
00207 int actTypeA = -1;
00208 if (actA)
00209 actTypeA = actA->getActivityType();
00210 int actTypeB = -1;
00211 if (actB)
00212 actTypeB = actB->getActivityType();
00213
00214 if (actTypeB == ActivityWidget::End &&
00215 actTypeA != ActivityWidget::Normal &&
00216 actTypeA != ActivityWidget::Branch &&
00217 dynamic_cast<ForkJoinWidget*>(widgetA) == NULL) {
00218 return false;
00219 }
00220
00221 if (actA != NULL && actTypeA != ActivityWidget::Branch) {
00222 AssociationWidgetList list = widgetA->getAssocList();
00223 for (AssociationWidget* assoc = list.first(); assoc; assoc = list.next()) {
00224 if (assoc->getWidget(A) == widgetA) {
00225 return false;
00226 }
00227 }
00228 }
00229 }
00230 return true;
00231 break;
00232
00233 case at_Anchor:
00234 return true;
00235 break;
00236
00237 default:
00238 kWarning() << "allowAssociation() on unknown type" << endl;
00239 break;
00240 }
00241 return false;
00242 }
00243
00244 bool AssocRules::allowRole( Association_Type assocType ) {
00245 for( int i = 0; i < m_nNumRules; i++ )
00246 if( assocType == m_AssocRules[ i ].assoc_type )
00247 return m_AssocRules[ i ].role;
00248 return false;
00249 }
00250
00251 bool AssocRules::allowMultiplicity( Association_Type assocType, Widget_Type widgetType ) {
00252 for( int i = 0; i < m_nNumRules; i++ )
00253 if( assocType == m_AssocRules[ i ].assoc_type )
00254 if( widgetType == m_AssocRules[ i ].widgetA_type || widgetType == m_AssocRules[ i ].widgetB_type )
00255 return m_AssocRules[ i ].multiplicity;
00256 return false;
00257 }
00258
00259 bool AssocRules::allowSelf( Association_Type assocType, Widget_Type widgetType ) {
00260 for( int i = 0; i < m_nNumRules; i++ )
00261 if( assocType == m_AssocRules[ i ].assoc_type )
00262 if( widgetType == m_AssocRules[ i ].widgetA_type || widgetType == m_AssocRules[ i ].widgetB_type )
00263 return m_AssocRules[ i ].self;
00264
00265 return false;
00266 }
00267
00268 Association_Type AssocRules::isGeneralisationOrRealisation(UMLWidget* widgetA, UMLWidget* widgetB) {
00269 Widget_Type widgetTypeA = widgetA->getBaseType();
00270 Widget_Type widgetTypeB = widgetB->getBaseType();
00271 for (int i = 0; i < m_nNumRules; i++) {
00272 if (m_AssocRules[i].assoc_type == at_Realization &&
00273 widgetTypeA == m_AssocRules[i].widgetA_type &&
00274 widgetTypeB == m_AssocRules[i].widgetB_type) {
00275 return at_Realization;
00276 }
00277 }
00278 return at_Generalization;
00279 }
00280
00281 AssocRules::Assoc_Rule AssocRules::m_AssocRules []= {
00282
00283
00284 { at_Association_Self,wt_Class, wt_Class, true, true, true, true },
00285 { at_Association_Self,wt_Object, wt_Object, true, true, true, true },
00286 { at_Association_Self,wt_Interface, wt_Interface, true, true, true, true },
00287 { at_Association, wt_Class, wt_Class, true, true, true, true },
00288 { at_Association, wt_Object, wt_Object, true, true, true, true },
00289 { at_Association, wt_Interface, wt_Interface, true, true, true, true },
00290 { at_Association, wt_Interface, wt_Class, true, true, true, false },
00291 { at_Association, wt_Class, wt_Interface, true, true, true, false },
00292 { at_Association, wt_Datatype, wt_Class, true, true, true, false },
00293 { at_Association, wt_Class, wt_Datatype, true, true, true, false },
00294 { at_Association, wt_Enum, wt_Class, true, true, true, false },
00295 { at_Association, wt_Class, wt_Enum, true, true, true, false },
00296 { at_Association, wt_Actor, wt_UseCase, true, false, false, false },
00297 { at_Association, wt_UseCase, wt_UseCase, true, false, false, false },
00298 { at_Association, wt_Actor, wt_Actor, true, false, false, false },
00299 { at_Association, wt_Actor, wt_UseCase, true, false, false, false },
00300 { at_Association, wt_Component, wt_Interface, true, false, false, false },
00301 { at_Association, wt_Interface, wt_Artifact, true, false, false, false },
00302 { at_Association, wt_Node, wt_Node, true, false, false, false },
00303 { at_UniAssociation,wt_Class, wt_Class, true, true, true, true },
00304 { at_UniAssociation,wt_Object, wt_Object, true, true, true, true },
00305 { at_UniAssociation,wt_Interface, wt_Interface, true, true, true, true },
00306 { at_UniAssociation,wt_Interface, wt_Class, true, true, true, true },
00307 { at_UniAssociation,wt_Class, wt_Interface, true, true, true, true },
00308 { at_UniAssociation,wt_Class, wt_Datatype, true, true, true, true },
00309 { at_UniAssociation,wt_Class, wt_Enum, true, true, true, true },
00310 { at_UniAssociation,wt_Actor, wt_Actor, true, false, false, false },
00311 { at_UniAssociation,wt_UseCase, wt_UseCase, true, false, false, false },
00312 { at_UniAssociation,wt_UseCase, wt_Actor, true, false, false, false },
00313 { at_Generalization,wt_Class, wt_Datatype, false, false, false, false },
00314 { at_Generalization,wt_Class, wt_Class, false, false, false, false },
00315 { at_Generalization,wt_Interface, wt_Interface, false, false, false, false },
00316 { at_Generalization,wt_UseCase, wt_UseCase, false, false, false, false },
00317 { at_Generalization,wt_Actor, wt_Actor, false, false, false, false },
00318 { at_Generalization,wt_Component, wt_Interface, false, false, false, false },
00319 { at_Aggregation, wt_Class, wt_Class, true, true, false, true },
00320 { at_Aggregation, wt_Class, wt_Interface, true, true, false, false },
00321 { at_Aggregation, wt_Class, wt_Enum, true, true, false, false },
00322 { at_Aggregation, wt_Class, wt_Datatype, true, true, false, false },
00323 { at_Dependency, wt_Class, wt_Class, true, false, false, true },
00324 { at_Dependency, wt_UseCase, wt_UseCase, true, false, false, false },
00325 { at_Dependency, wt_Actor, wt_Actor, true, false, false, false },
00326 { at_Dependency, wt_Actor, wt_UseCase, true, false, false, false },
00327 { at_Dependency, wt_Package, wt_Package, true, true, true, true },
00328 { at_Dependency, wt_Package, wt_Class, true, true, true, true },
00329 { at_Dependency, wt_Class, wt_Package, true, true, true, true },
00330 { at_Dependency, wt_Package, wt_Interface, true, true, true, true },
00331 { at_Dependency, wt_Interface, wt_Package, true, true, true, true },
00332 { at_Dependency, wt_Interface, wt_Interface, true, true, true, true },
00333 { at_Dependency, wt_Interface, wt_Class, true, true, true, true },
00334 { at_Dependency, wt_Class, wt_Interface, true, true, true, true },
00335 { at_Dependency, wt_Class, wt_Datatype, true, true, true, true },
00336 { at_Dependency, wt_Class, wt_Enum, true, true, true, true },
00337 { at_Dependency, wt_Component, wt_Component, true, true, true, true },
00338 { at_Dependency, wt_Component, wt_Interface, true, true, true, true },
00339 { at_Dependency, wt_Component, wt_Artifact, true, false, false, false },
00340 { at_Dependency, wt_Node, wt_Component, true, false, false, false },
00341 { at_Realization, wt_Class, wt_Interface, false, false, false, false },
00342 { at_Realization, wt_Interface, wt_Package, false, false, false, false },
00343 { at_Realization, wt_Interface, wt_Interface, false, false, false, false },
00344 { at_Realization, wt_Component, wt_Interface, false, false, false, false },
00345 { at_Realization, wt_Package, wt_Interface, false, false, false, false },
00346 { at_Composition, wt_Class, wt_Class, true, true, false, true },
00347 { at_Composition, wt_Class, wt_Interface, true, true, false, false },
00348 { at_Composition, wt_Class, wt_Enum, true, true, false, false },
00349 { at_Composition, wt_Class, wt_Datatype, false, false, false, false },
00350 { at_Composition, wt_Class, wt_Class, false, false, false, false },
00351 { at_Containment, wt_Package, wt_Class, false, false, true, false },
00352 { at_Containment, wt_Package, wt_Interface, false, false, true, false },
00353 { at_Containment, wt_Package, wt_Enum, false, false, true, false },
00354 { at_Containment, wt_Package, wt_Package, false, false, true, false },
00355 { at_Containment, wt_Package, wt_Component, false, false, true, false },
00356 { at_Containment, wt_Class, wt_Class, false, false, true, false },
00357 { at_Containment, wt_Class, wt_Interface, false, false, true, false },
00358 { at_Containment, wt_Class, wt_Enum, false, false, true, false },
00359 { at_Containment, wt_Interface, wt_Class, false, false, true, false },
00360 { at_Containment, wt_Interface, wt_Interface, false, false, true, false },
00361 { at_Containment, wt_Interface, wt_Enum, false, false, true, false },
00362 { at_Containment, wt_Component, wt_Component, false, false, true, false },
00363 { at_Containment, wt_Component, wt_Artifact, false, false, true, false },
00364 { at_Coll_Message, wt_Object, wt_Object, true, false, true, true },
00365 { at_State, wt_State, wt_State, true, false, true, true },
00366 { at_State, wt_ForkJoin, wt_State, true, false, true, true },
00367 { at_State, wt_State, wt_ForkJoin, true, false, true, true },
00368 { at_Activity, wt_Activity, wt_Activity, true, false, true, true },
00369 { at_Activity, wt_ForkJoin, wt_Activity, true, false, true, true },
00370 { at_Activity, wt_Activity, wt_ForkJoin, true, false, true, true },
00371 { at_Anchor, wt_Class, wt_Note, false, false, false, false },
00372 { at_Anchor, wt_Package, wt_Note, false, false, false, false },
00373 { at_Anchor, wt_Interface, wt_Note, false, false, false, false },
00374 { at_Anchor, wt_Datatype, wt_Note, false, false, false, false },
00375 { at_Anchor, wt_Enum, wt_Note, false, false, false, false },
00376 { at_Anchor, wt_Object, wt_Note, false, false, false, false },
00377 { at_Anchor, wt_Actor, wt_Note, false, false, false, false },
00378 { at_Anchor, wt_UseCase, wt_Note, false, false, false, false },
00379 { at_Anchor, wt_Message, wt_Note, false, false, false, false },
00380 { at_Anchor, wt_State, wt_Note, false, false, false, false },
00381 { at_Anchor, wt_Activity, wt_Note, false, false, false, false },
00382 { at_Relationship, wt_Entity, wt_Entity, true, true, true, true },
00383 };
00384
00385 int AssocRules::m_nNumRules = sizeof( m_AssocRules ) / sizeof( AssocRules::Assoc_Rule );
00386