Coverage Report - org.argouml.model.mdr.MDRModelImplementation
 
Classes in this File Line Coverage Branch Coverage Complexity
MDRModelImplementation
73%
168/228
51%
33/64
1.692
MDRModelImplementation$Extent
77%
7/9
N/A
1.692
 
 1  
 /* $Id: MDRModelImplementation.java 18760 2010-09-18 05:19:53Z tfmorris $
 2  
  *****************************************************************************
 3  
  * Copyright (c) 2005,2010 Contributors - see below
 4  
  * All rights reserved. This program and the accompanying materials
 5  
  * are made available under the terms of the Eclipse Public License v1.0
 6  
  * which accompanies this distribution, and is available at
 7  
  * http://www.eclipse.org/legal/epl-v10.html
 8  
  *
 9  
  * Contributors:
 10  
  *    Tom Morris
 11  
  *****************************************************************************
 12  
  *
 13  
  * Some portions of this file was previously release using the BSD License:
 14  
  */
 15  
 
 16  
 // Copyright (c) 2005-2008 The Regents of the University of California. All
 17  
 // Rights Reserved. Permission to use, copy, modify, and distribute this
 18  
 // software and its documentation without fee, and without a written
 19  
 // agreement is hereby granted, provided that the above copyright notice
 20  
 // and this paragraph appear in all copies. This software program and
 21  
 // documentation are copyrighted by The Regents of the University of
 22  
 // California. The software program and documentation are supplied "AS
 23  
 // IS", without any accompanying services from The Regents. The Regents
 24  
 // does not warrant that the operation of the program will be
 25  
 // uninterrupted or error-free. The end-user understands that the program
 26  
 // was developed for research purposes and is advised not to rely
 27  
 // exclusively on the program for any reason. IN NO EVENT SHALL THE
 28  
 // UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
 29  
 // SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS,
 30  
 // ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
 31  
 // THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
 32  
 // SUCH DAMAGE. THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY
 33  
 // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 34  
 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
 35  
 // PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
 36  
 // CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT,
 37  
 // UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 38  
 
 39  
 package org.argouml.model.mdr;
 40  
 
 41  
 import java.io.IOException;
 42  
 import java.io.OutputStream;
 43  
 import java.net.URL;
 44  
 import java.util.ArrayList;
 45  
 import java.util.Arrays;
 46  
 import java.util.Collection;
 47  
 import java.util.Collections;
 48  
 import java.util.HashMap;
 49  
 import java.util.List;
 50  
 import java.util.Map;
 51  
 
 52  
 import javax.jmi.model.ModelPackage;
 53  
 import javax.jmi.model.MofPackage;
 54  
 import javax.jmi.reflect.InvalidObjectException;
 55  
 import javax.jmi.reflect.RefObject;
 56  
 import javax.jmi.reflect.RefPackage;
 57  
 import javax.jmi.xmi.MalformedXMIException;
 58  
 
 59  
 import org.apache.log4j.Logger;
 60  
 import org.argouml.model.ActivityGraphsFactory;
 61  
 import org.argouml.model.ActivityGraphsHelper;
 62  
 import org.argouml.model.AggregationKind;
 63  
 import org.argouml.model.ChangeableKind;
 64  
 import org.argouml.model.CollaborationsFactory;
 65  
 import org.argouml.model.CollaborationsHelper;
 66  
 import org.argouml.model.CommonBehaviorFactory;
 67  
 import org.argouml.model.CommonBehaviorHelper;
 68  
 import org.argouml.model.ConcurrencyKind;
 69  
 import org.argouml.model.CoreFactory;
 70  
 import org.argouml.model.CoreHelper;
 71  
 import org.argouml.model.DataTypesFactory;
 72  
 import org.argouml.model.DataTypesHelper;
 73  
 import org.argouml.model.DiagramInterchangeModel;
 74  
 import org.argouml.model.DirectionKind;
 75  
 import org.argouml.model.ExtensionMechanismsFactory;
 76  
 import org.argouml.model.ExtensionMechanismsHelper;
 77  
 import org.argouml.model.Facade;
 78  
 import org.argouml.model.MetaTypes;
 79  
 import org.argouml.model.ModelEventPump;
 80  
 import org.argouml.model.ModelImplementation;
 81  
 import org.argouml.model.ModelManagementFactory;
 82  
 import org.argouml.model.ModelManagementHelper;
 83  
 import org.argouml.model.OrderingKind;
 84  
 import org.argouml.model.PseudostateKind;
 85  
 import org.argouml.model.ScopeKind;
 86  
 import org.argouml.model.StateMachinesFactory;
 87  
 import org.argouml.model.StateMachinesHelper;
 88  
 import org.argouml.model.UUIDManager;
 89  
 import org.argouml.model.UmlException;
 90  
 import org.argouml.model.UmlFactory;
 91  
 import org.argouml.model.UmlHelper;
 92  
 import org.argouml.model.UseCasesFactory;
 93  
 import org.argouml.model.UseCasesHelper;
 94  
 import org.argouml.model.VisibilityKind;
 95  
 import org.argouml.model.XmiReader;
 96  
 import org.argouml.model.XmiWriter;
 97  
 import org.netbeans.api.mdr.CreationFailedException;
 98  
 import org.netbeans.api.mdr.MDRManager;
 99  
 import org.netbeans.api.mdr.MDRepository;
 100  
 import org.netbeans.api.xmi.XMIReader;
 101  
 import org.netbeans.api.xmi.XMIReaderFactory;
 102  
 import org.omg.uml.UmlPackage;
 103  
 
 104  
 /**
 105  
  * The handle to find all helper and factories.
 106  
  */
 107  
 public class MDRModelImplementation implements ModelImplementation {
 108  
 
 109  
     /**
 110  
      * Logger.
 111  
      */
 112  900
     private static final Logger LOG =
 113  
         Logger.getLogger(MDRModelImplementation.class);
 114  
 
 115  
     private Facade theFacade;
 116  
 
 117  
     private ModelEventPumpMDRImpl theModelEventPump;
 118  
 
 119  
     private CopyHelper theCopyHelper;
 120  
 
 121  
     private ActivityGraphsHelper theActivityGraphsHelper;
 122  
 
 123  
     private CoreHelper theCoreHelper;
 124  
 
 125  900
     private MetaTypes theMetaTypes = new MetaTypesMDRImpl();
 126  
 
 127  
     private ModelManagementFactory theModelManagementFactory;
 128  
 
 129  
     private ModelManagementHelper theModelManagementHelper;
 130  
 
 131  
     private StateMachinesHelper theStateMachinesHelper;
 132  
 
 133  
     private UmlFactory theUmlFactory;
 134  
 
 135  
     private UmlHelper theUmlHelper;
 136  
 
 137  
     private UseCasesFactory theUseCasesFactory;
 138  
 
 139  
     private UseCasesHelper theUseCasesHelper;
 140  
 
 141  
     private ActivityGraphsFactory theActivityGraphsFactory;
 142  
 
 143  
     private CollaborationsFactory theCollaborationsFactory;
 144  
 
 145  
     private CollaborationsHelper theCollaborationsHelper;
 146  
 
 147  
     private CommonBehaviorFactory theCommonBehaviorFactory;
 148  
 
 149  
     private CommonBehaviorHelper theCommonBehaviorHelper;
 150  
 
 151  
     private DataTypesFactoryMDRImpl theDataTypesFactory;
 152  
 
 153  
     private DataTypesHelper theDataTypesHelper;
 154  
 
 155  
     private ExtensionMechanismsFactory theExtensionMechanismsFactory;
 156  
 
 157  
     private ExtensionMechanismsHelper theExtensionMechanismsHelper;
 158  
 
 159  
     private StateMachinesFactory theStateMachinesFactory;
 160  
 
 161  
     private CoreFactory theCoreFactory;
 162  
 
 163  
     private KindsMDRImpl theKindsObject;
 164  
 
 165  
     private MDRepository repository;
 166  
 
 167  
     /**
 168  
      * Package containing user UML model.
 169  
      */
 170  
     private UmlPackage umlPackage;
 171  
 
 172  
     /**
 173  
      * MOF Package containing UML metamodel (M2).
 174  
      */
 175  
     private MofPackage mofPackage;
 176  
 
 177  
     /**
 178  
      * Top level MOF extent.
 179  
      */
 180  
     private ModelPackage mofExtent;
 181  
 
 182  
     /**
 183  
      * Map of model elements to xmi.ids used to keep xmi.ids stable
 184  
      * across read/write cycles.
 185  
      */
 186  900
     private Map<String, XmiReference> objectToId = 
 187  
         Collections.synchronizedMap(new HashMap<String, XmiReference>());
 188  
     
 189  
     /**
 190  
      * Set of known public IDs of models that could be used to resolve URLs 
 191  
      * from model element IDs.
 192  
      */
 193  900
     private Map<String, String> public2SystemIds = 
 194  
         Collections.synchronizedMap(new HashMap<String, String>());
 195  
     
 196  
     /**
 197  
      * Index of objects keyed by system ID, then xmi.id within that file
 198  
      */
 199  900
     private Map<String, Map<String, Object>> idToObject = 
 200  
         Collections.synchronizedMap(new HashMap<String, Map<String, Object>>());
 201  
 
 202  900
     private List<String> searchDirs = new ArrayList<String>();
 203  
     
 204  
     
 205  
     /**
 206  
      * Set of extents and their read-only status. 
 207  
      */
 208  900
     private Map<UmlPackage, Extent> extents = 
 209  
         new HashMap<UmlPackage, Extent>(10, (float) .5);
 210  
 
 211  
     private class Extent {
 212  1868
         int refCount = 0;
 213  1868
         boolean readOnly = false;
 214  
         String name;
 215  
         
 216  1868
         Extent(String name, boolean readOnly) {
 217  1868
             this.name = name;
 218  1868
             this.readOnly = readOnly;
 219  1868
         }
 220  
         
 221  
         int getRefCount() {
 222  0
             return refCount;
 223  
         }
 224  
         
 225  
         synchronized int decrementCount() {
 226  68
             return refCount--;
 227  
         }
 228  
         
 229  
         synchronized int incrementCount() {
 230  0
             return refCount++;
 231  
         }
 232  
     }
 233  
     
 234  
     /**
 235  
      * @return Returns the root UML Factory package for user model.
 236  
      * @deprecated for 0.26. Use RefObject.refOutermostPackage instead if at all
 237  
      *             possible. In some cases (like an unqualified createClass()),
 238  
      *             additional infrastructure work is required in the ArgoUML app
 239  
      *             before this will be possible.
 240  
      */
 241  
     public UmlPackage getUmlPackage() {
 242  2090
         synchronized (extents) {
 243  2090
             if (umlPackage == null) {
 244  0
                 LOG.debug("umlPackage is null - no current extent");
 245  
             }
 246  2090
             return umlPackage;
 247  0
         }
 248  
     }
 249  
 
 250  
     RefPackage createExtent(String name, boolean readOnly) {
 251  
         try {
 252  1868
             synchronized (extents) {
 253  1868
                 UmlPackage extent = (UmlPackage) getRepository().createExtent(
 254  
                         name, getMofPackage());
 255  1868
                 extents.put(extent, new Extent(name,readOnly));
 256  
                 
 257  1868
                 if (!readOnly) {
 258  
                     // TODO: This will need to change when we support multiple
 259  
                     // user models.
 260  
 
 261  
                     // Delete the old extent first
 262  968
                     if (umlPackage != null) {
 263  
                         try {
 264  0
                             deleteExtentUnchecked(umlPackage);
 265  0
                         } catch (InvalidObjectException e) {
 266  0
                             LOG.debug("User model extent already deleted");
 267  0
                         }
 268  
                     }
 269  968
                     umlPackage = extent;
 270  
                 }
 271  1868
                 if (LOG.isDebugEnabled()) {
 272  0
                     LOG.debug("Created new " + (readOnly ? "readonly " : "")
 273  
                             + "extent " + umlPackage);
 274  0
                     LOG.debug("All registered extents = "
 275  
                             + Arrays.toString(repository.getExtentNames()));
 276  
                 }
 277  1868
                 return extent;
 278  0
             }
 279  0
         } catch (CreationFailedException e) {
 280  0
             LOG.error("Extent creation failed for " + name);
 281  0
             return null;
 282  
         }
 283  
     }
 284  
 
 285  
 
 286  
     /**
 287  
      * Delete all extents except those for the UML metamodel and the 
 288  
      * meta-meta model (ie MOF).
 289  
      */
 290  
     private void cleanExtents() {
 291  900
         String[] names = repository.getExtentNames();
 292  2700
         for (String n : names) {
 293  1800
             if (!MOF_EXTENT_NAME.equals(n) && !"MOF".equals(n)) {
 294  0
                 RefPackage extent = repository.getExtent(n);
 295  0
                 extent.refDelete();
 296  0
                 LOG.debug("Deleting extent " + n);
 297  
             }
 298  
         }
 299  900
     }
 300  
     
 301  
     void deleteExtent(UmlPackage extent) {
 302  68
         synchronized (extents) {
 303  68
             if (umlPackage.equals(extent)) {
 304  
                 // Make sure we always have a default extent.
 305  
                 // The old extent will get deleted as part of creating the
 306  
                 // new extent.
 307  68
                 createDefaultExtent();
 308  
             } else {
 309  0
                 deleteExtentUnchecked(extent);
 310  
             }
 311  68
         }
 312  68
     }
 313  
 
 314  
     private void deleteExtentUnchecked(UmlPackage extent) {
 315  68
         synchronized (extents) {
 316  68
             Extent e = extents.get(extent);
 317  68
             if (e == null) {
 318  0
                 LOG.warn("No listing for extent " + extent);
 319  0
                 extent.refDelete();
 320  
             } else {
 321  68
                 if (e.decrementCount() == 0) {
 322  
 
 323  68
                     String name = extents.remove(extent).name;
 324  68
                     if (public2SystemIds.remove(name) == null) {
 325  68
                         if (!"model extent".equals(name)) {
 326  0
                             LOG.warn("No system id found for extent "
 327  
                                     + (name == null ? "" : name) + " : "
 328  
                                     + extent);
 329  
                         }
 330  
                     }
 331  68
                     if (idToObject.remove(name) == null) {
 332  68
                         if (!"model extent".equals(name)) {
 333  0
                             LOG.warn("No ID map found for extent "
 334  
                                     + (name == null ? "" : name) + " : "
 335  
                                     + extent);
 336  
                         }
 337  
                     }
 338  
                     // TODO: Need to clean up objectToId
 339  
                     // (can we do it based on modelelement delete
 340  
                     // notifications?)
 341  68
                     extent.refDelete();
 342  
                 }
 343  
             }
 344  68
         }
 345  68
     }
 346  
     
 347  
     Collection<UmlPackage> getExtents() {
 348  0
         return Collections.unmodifiableSet(extents.keySet());
 349  
     }
 350  
     
 351  
     public UmlPackage getExtent(String name) {
 352  900
         return (UmlPackage) repository.getExtent(name);
 353  
     }
 354  
     
 355  
     boolean isReadOnly(Object extent) {
 356  2149
         synchronized (extents) {
 357  2149
             Extent result = extents.get(extent);
 358  2149
             if (result == null) {
 359  
 //                LOG.warn("Unable to find extent " + extent);
 360  0
                 return false;
 361  
             } 
 362  2149
             return result.readOnly;
 363  0
         }
 364  
     }
 365  
     
 366  
     /**
 367  
      * @return MOF Package containing UML metamodel (M2).
 368  
      */
 369  
     public MofPackage getMofPackage() {
 370  1868
         return mofPackage;
 371  
     }
 372  
 
 373  
     /**
 374  
      * @return Top level MOF extent.
 375  
      */
 376  
     ModelPackage getModelPackage() {
 377  9878
         return mofExtent;
 378  
     }
 379  
 
 380  
     /**
 381  
      * @return The MDRepository.
 382  
      */
 383  
     MDRepository getRepository() {
 384  3688
         return repository;
 385  
     }
 386  
 
 387  
     static final String MOF_EXTENT_NAME = "MOF Extent";
 388  
 
 389  
     static final String MODEL_EXTENT_NAME = "model extent";
 390  
 
 391  
     /**
 392  
      * UML 1.4 metamodel definition in XMI format.
 393  
      */
 394  
     static final String METAMODEL_URL = "mof/01-02-15_Diff.xml";
 395  
 
 396  
 
 397  
     /**
 398  
      * Constructor intended for use by decorators which need to override some of
 399  
      * the bootstrapping logic. Decorators must call
 400  
      * {@link #initializeFactories} on the new model after loading the default
 401  
      * extent.
 402  
      * 
 403  
      * @param r the underlying repository implementation
 404  
      * @throws UmlException on any fatal error. Actual cause will be inclused as
 405  
      *             a nested exception
 406  
      */
 407  900
     public MDRModelImplementation(MDRepository r) throws UmlException {
 408  900
         repository = r;
 409  900
         initializeM2();
 410  900
     }
 411  
     
 412  
     /**
 413  
      * Constructor.
 414  
      *
 415  
      * @throws UmlException if construction fails.  Some possible nested 
 416  
      * exceptions include:
 417  
      * <ul>
 418  
      * <el>CreationFailedException - If the creation of the Extent fail</el>
 419  
      * <el>MalformedXMIException If the metamodel XMI is badly formed</el>
 420  
      * <el>IOException If there is a problem opening a file</el>
 421  
      * </ul>
 422  
      */
 423  
     public MDRModelImplementation() throws UmlException {
 424  900
         this(getDefaultRepository());
 425  
 
 426  900
         cleanExtents();
 427  900
         createDefaultExtent();
 428  900
         if (umlPackage == null) {
 429  0
             throw new UmlException("Could not create UML extent");
 430  
         }
 431  900
         LOG.debug("MDR Init - created UML extent");
 432  
 
 433  900
         initializeFactories(umlPackage);
 434  900
     }
 435  
 
 436  
     private static MDRepository getDefaultRepository() {
 437  900
         LOG.debug("Starting MDR system initialization");
 438  
 
 439  900
         String storageImplementation =
 440  
             System.getProperty(
 441  
                 "org.netbeans.mdr.storagemodel.StorageFactoryClassName",
 442  
                 "org.netbeans.mdr.persistence.memoryimpl.StorageFactoryImpl");
 443  900
         System.setProperty(
 444  
                 "org.netbeans.mdr.storagemodel.StorageFactoryClassName",
 445  
                 storageImplementation);
 446  
 
 447  
         /*
 448  
          * Set the storage id for our repository so that MofIds will be unique
 449  
          * (they are composed as "storageId":"serialNumber"). NOTE: The storage
 450  
          * manager only looks for a few property names such as the
 451  
          * StorageFactoryClassName. Everything else needs to be prefixed with
 452  
          * "MDRStorageProperty." which gets deleted from the property name
 453  
          * before it and its associated value are copied to an *internal*
 454  
          * property table separate from the system property table.
 455  
          */
 456  900
         System.setProperty(
 457  
                 "MDRStorageProperty.org.netbeans.mdr.persistence.memoryimpl.id",
 458  
                 UUIDManager.getInstance().getNewUUID());
 459  
 
 460  
         // Connect to the repository
 461  900
         MDRepository defaultRepository = 
 462  
             MDRManager.getDefault().getDefaultRepository();
 463  900
         LOG.debug("MDR Init - got default repository");
 464  900
         return defaultRepository;
 465  
     }
 466  
 
 467  
 
 468  
     private void initializeM2() throws UmlException {
 469  900
         mofExtent = (ModelPackage) repository.getExtent(MOF_EXTENT_NAME);
 470  900
         LOG.debug("MDR Init - tried to get MOF extent");
 471  
 
 472  
         // Create an extent and read in our metamodel (M2 model)
 473  900
         if (mofExtent == null) {
 474  
 
 475  
             try {
 476  900
                 mofExtent = 
 477  
                     (ModelPackage) repository.createExtent(MOF_EXTENT_NAME);
 478  0
             } catch (CreationFailedException e) {
 479  0
                 throw new UmlException(e);
 480  900
             }
 481  900
             LOG.debug("MDR Init - created MOF extent");
 482  900
             XMIReader reader = XMIReaderFactory.getDefault().createXMIReader();
 483  900
             LOG.debug("MDR Init - created XMI reader");
 484  900
             String metafacade =
 485  
                 System.getProperty("argouml.model.mdr.facade", METAMODEL_URL);
 486  900
             URL resource = getClass().getResource(metafacade);
 487  
             try {
 488  900
                 reader.read(resource.toString(), mofExtent);
 489  0
             } catch (IOException e) {
 490  0
                 throw new UmlException(e);
 491  0
             } catch (MalformedXMIException e) {
 492  0
                 throw new UmlException(e);
 493  900
             }
 494  900
             LOG.debug("MDR Init - read UML metamodel");
 495  
         }
 496  
 
 497  900
         mofPackage = null;
 498  900
         for (MofPackage pkg : (Collection<MofPackage>) mofExtent
 499  
                 .getMofPackage().refAllOfClass()) {
 500  900
             if ("UML".equals(pkg.getName())) {
 501  900
                 mofPackage = pkg;
 502  900
                 break;
 503  
             }
 504  
         }
 505  900
     }
 506  
 
 507  
     /**
 508  
      * Initialize factories and other sub-objects.  The default constructor
 509  
      * takes care of this automatically, but decorating implementations
 510  
      * using the non-default constructor need to call it after they
 511  
      * have loaded the default extent.
 512  
      *
 513  
      * @param up default UmlPackage instance which has been created or loaded
 514  
      */
 515  
     public void initializeFactories(UmlPackage up) {
 516  900
         umlPackage = up;
 517  
         
 518  
         // Create and start event pump first so it's available for all others
 519  900
         theModelEventPump = new ModelEventPumpMDRImpl(this, repository);
 520  900
         theModelEventPump.startPumpingEvents();
 521  900
         LOG.debug("MDR Init - event pump started");
 522  
 
 523  
         // DataTypes is next so it's available for Kinds, ModelManagement,
 524  
         // & Extensions
 525  900
         theDataTypesFactory = new DataTypesFactoryMDRImpl(this);
 526  900
         theDataTypesHelper = new DataTypesHelperMDRImpl(this);
 527  
 
 528  900
         theKindsObject = new KindsMDRImpl(this);
 529  900
         theModelManagementFactory = new ModelManagementFactoryMDRImpl(this);
 530  900
         theExtensionMechanismsHelper =
 531  
             new ExtensionMechanismsHelperMDRImpl(this);
 532  900
         theExtensionMechanismsFactory =
 533  
             new ExtensionMechanismsFactoryMDRImpl(this);
 534  900
         LOG.debug("MDR Init - initialized package Extension mechanism");
 535  
 
 536  
         // Initialize remaining factories and helpers
 537  
         // (but defer heavyweight ones until needed)
 538  900
         theCopyHelper = new CopyHelper(this);
 539  900
         theActivityGraphsHelper = new ActivityGraphsHelperMDRImpl();
 540  900
         theCoreHelper = 
 541  
             new UndoCoreHelperDecorator(new CoreHelperMDRImpl(this));
 542  900
         LOG.debug("MDR Init - initialized package Core helper");
 543  900
         theModelManagementHelper = new ModelManagementHelperMDRImpl(this);
 544  900
         theStateMachinesHelper = new StateMachinesHelperMDRImpl(this);
 545  900
         LOG.debug("MDR Init - initialized package StateMachines");
 546  900
         theUseCasesFactory = new UseCasesFactoryMDRImpl(this);
 547  900
         theUseCasesHelper = new UseCasesHelperMDRImpl(this);
 548  900
         LOG.debug("MDR Init - initialized package Use Cases");
 549  900
         theActivityGraphsFactory = new ActivityGraphsFactoryMDRImpl(this);
 550  900
         LOG.debug("MDR Init - initialized package Collaborations");
 551  900
         theCommonBehaviorFactory = new CommonBehaviorFactoryMDRImpl(this);
 552  900
         theCommonBehaviorHelper = new CommonBehaviorHelperMDRImpl(this);
 553  900
         LOG.debug("MDR Init - initialized package CommonBehavior");
 554  900
         theStateMachinesFactory = new StateMachinesFactoryMDRImpl(this);
 555  900
         theCoreFactory = new CoreFactoryMDRImpl(this);
 556  900
         LOG.debug("MDR Init - all packages initialized");
 557  
 
 558  900
     }
 559  
 
 560  
 
 561  
     RefPackage createDefaultExtent() {
 562  
         // Create a default extent for the user UML model. This will get
 563  
         // replaced if a new model is read in from an XMI file.
 564  968
         synchronized (extents) {
 565  968
             umlPackage = (UmlPackage) repository.getExtent(MODEL_EXTENT_NAME);
 566  968
             if (umlPackage != null) {
 567  
                 // NOTE: If we switch to a persistent repository like the b-tree
 568  
                 // repository we'll want to keep the old extent(s) around
 569  
                 try {
 570  68
                     UmlPackage oldPackage = umlPackage;
 571  68
                     umlPackage = null;
 572  68
                     deleteExtentUnchecked(oldPackage);
 573  68
                     LOG.debug("MDR Init - UML extent existed - "
 574  
                             + "deleted it and all UML data");
 575  0
                 } catch (InvalidObjectException e) {
 576  0
                     LOG.debug("Got error deleting old default user extent");
 577  68
                 }
 578  
             }
 579  968
             umlPackage = (UmlPackage) createExtent(MODEL_EXTENT_NAME, false);
 580  968
             LOG.debug("Created default extent");
 581  968
             return umlPackage;
 582  0
         }
 583  
     }
 584  
 
 585  
     /**
 586  
      * Shutdown repository in a graceful fashion
 587  
      * (currently unused).
 588  
      */
 589  
     public void shutdown() {
 590  0
         theModelEventPump.flushModelEvents();
 591  0
         theModelEventPump.stopPumpingEvents();
 592  0
         MDRManager.getDefault().shutdownAll();
 593  0
     }
 594  
 
 595  
     /*
 596  
      * @see org.argouml.model.ModelImplementation#getDiagramInterchangeModel()
 597  
      */
 598  
     public DiagramInterchangeModel getDiagramInterchangeModel() {
 599  2097
         return null;
 600  
     }
 601  
 
 602  
     /*
 603  
      * @see org.argouml.model.ModelImplementation#getFacade()
 604  
      */
 605  
     public Facade getFacade() {
 606  4850070
         if (theFacade == null) {
 607  900
             theFacade = new FacadeMDRImpl(this);
 608  
         }
 609  4850069
         return theFacade;
 610  
     }
 611  
 
 612  
     /*
 613  
      * @see org.argouml.model.ModelImplementation#getModelEventPump()
 614  
      */
 615  
     public ModelEventPump getModelEventPump() {
 616  8013
         return theModelEventPump;
 617  
     }
 618  
 
 619  
     /*
 620  
      * @see org.argouml.model.ModelImplementation#getActivityGraphsFactory()
 621  
      */
 622  
     public ActivityGraphsFactory getActivityGraphsFactory() {
 623  19
         return theActivityGraphsFactory;
 624  
     }
 625  
 
 626  
     /*
 627  
      * @see org.argouml.model.ModelImplementation#getActivityGraphsHelper()
 628  
      */
 629  
     public ActivityGraphsHelper getActivityGraphsHelper() {
 630  900
         return theActivityGraphsHelper;
 631  
     }
 632  
 
 633  
     /*
 634  
      * @see org.argouml.model.ModelImplementation#getCollaborationsFactory()
 635  
      */
 636  
     public CollaborationsFactory getCollaborationsFactory() {
 637  38
         if (theCollaborationsFactory == null) {
 638  38
             theCollaborationsFactory =
 639  
                 new CollaborationsFactoryMDRImpl(this);
 640  
         }
 641  38
         return theCollaborationsFactory;
 642  
     }
 643  
 
 644  
     /*
 645  
      * @see org.argouml.model.ModelImplementation#getCollaborationsHelper()
 646  
      */
 647  
     public CollaborationsHelper getCollaborationsHelper() {
 648  900
         if (theCollaborationsHelper == null) {
 649  900
             theCollaborationsHelper =
 650  
                 new CollaborationsHelperMDRImpl(this);
 651  
         }
 652  900
         return theCollaborationsHelper;
 653  
     }
 654  
 
 655  
     /*
 656  
      * @see org.argouml.model.ModelImplementation#getCommonBehaviorFactory()
 657  
      */
 658  
     public CommonBehaviorFactory getCommonBehaviorFactory() {
 659  0
         return theCommonBehaviorFactory;
 660  
     }
 661  
 
 662  
     /*
 663  
      * @see org.argouml.model.ModelImplementation#getCommonBehaviorHelper()
 664  
      */
 665  
     public CommonBehaviorHelper getCommonBehaviorHelper() {
 666  900
         return theCommonBehaviorHelper;
 667  
     }
 668  
 
 669  
     /*
 670  
      * @see org.argouml.model.ModelImplementation#getCopyHelper()
 671  
      */
 672  
     public org.argouml.model.CopyHelper getCopyHelper() {
 673  0
         return theCopyHelper;
 674  
     }
 675  
 
 676  
     /*
 677  
      * @see org.argouml.model.ModelImplementation#getCoreFactory()
 678  
      */
 679  
     public CoreFactory getCoreFactory() {
 680  4
         return theCoreFactory;
 681  
     }
 682  
 
 683  
     /*
 684  
      * @see org.argouml.model.ModelImplementation#getCoreHelper()
 685  
      */
 686  
     public CoreHelper getCoreHelper() {
 687  902
         return theCoreHelper;
 688  
     }
 689  
 
 690  
     /*
 691  
      * @see org.argouml.model.ModelImplementation#getDataTypesFactory()
 692  
      */
 693  
     public DataTypesFactory getDataTypesFactory() {
 694  0
         return theDataTypesFactory;
 695  
     }
 696  
 
 697  
     DataTypesFactoryMDRImpl getDataTypesFactoryInternal() {
 698  0
         return theDataTypesFactory;
 699  
     }
 700  
     
 701  
     /*
 702  
      * @see org.argouml.model.ModelImplementation#getDataTypesHelper()
 703  
      */
 704  
     public DataTypesHelper getDataTypesHelper() {
 705  900
         return theDataTypesHelper;
 706  
     }
 707  
 
 708  
     /*
 709  
      * @see org.argouml.model.ModelImplementation#getExtensionMechanismsFactory()
 710  
      */
 711  
     public ExtensionMechanismsFactory getExtensionMechanismsFactory() {
 712  14
         return theExtensionMechanismsFactory;
 713  
     }
 714  
 
 715  
     /*
 716  
      * @see org.argouml.model.ModelImplementation#getExtensionMechanismsHelper()
 717  
      */
 718  
     public ExtensionMechanismsHelper getExtensionMechanismsHelper() {
 719  1800
         return theExtensionMechanismsHelper;
 720  
     }
 721  
 
 722  
     /*
 723  
      * @see org.argouml.model.ModelImplementation#getModelManagementFactory()
 724  
      */
 725  
     public ModelManagementFactory getModelManagementFactory() {
 726  5808
         return theModelManagementFactory;
 727  
     }
 728  
 
 729  
     /*
 730  
      * @see org.argouml.model.ModelImplementation#getModelManagementHelper()
 731  
      */
 732  
     public ModelManagementHelper getModelManagementHelper() {
 733  11423
         return theModelManagementHelper;
 734  
     }
 735  
 
 736  
     /*
 737  
      * @see org.argouml.model.ModelImplementation#getStateMachinesFactory()
 738  
      */
 739  
     public StateMachinesFactory getStateMachinesFactory() {
 740  101
         return theStateMachinesFactory;
 741  
     }
 742  
 
 743  
     /*
 744  
      * @see org.argouml.model.ModelImplementation#getStateMachinesHelper()
 745  
      */
 746  
     public StateMachinesHelper getStateMachinesHelper() {
 747  900
         return theStateMachinesHelper;
 748  
     }
 749  
 
 750  
     /*
 751  
      * @see org.argouml.model.ModelImplementation#getUmlFactory()
 752  
      */
 753  
     public UmlFactory getUmlFactory() {
 754  388137
         if (theUmlFactory == null) {
 755  900
             theUmlFactory = new UmlFactoryMDRImpl(this);
 756  
         }
 757  388137
         return theUmlFactory;
 758  
     }
 759  
 
 760  
     /*
 761  
      * @see org.argouml.model.ModelImplementation#getUmlHelper()
 762  
      */
 763  
     public UmlHelper getUmlHelper() {
 764  908
         if (theUmlHelper == null) {
 765  900
             theUmlHelper = new UmlHelperMDRImpl(this);
 766  
         }
 767  908
         return theUmlHelper;
 768  
     }
 769  
 
 770  
     /*
 771  
      * @see org.argouml.model.ModelImplementation#getUseCasesFactory()
 772  
      */
 773  
     public UseCasesFactory getUseCasesFactory() {
 774  0
         return theUseCasesFactory;
 775  
     }
 776  
 
 777  
     /*
 778  
      * @see org.argouml.model.ModelImplementation#getUseCasesHelper()
 779  
      */
 780  
     public UseCasesHelper getUseCasesHelper() {
 781  900
         return theUseCasesHelper;
 782  
     }
 783  
 
 784  
     /*
 785  
      * @see org.argouml.model.ModelImplementation#getMetaTypes()
 786  
      */
 787  
     public MetaTypes getMetaTypes() {
 788  156992
         return theMetaTypes;
 789  
     }
 790  
 
 791  
     /*
 792  
      * @see org.argouml.model.ModelImplementation#getChangeableKind()
 793  
      */
 794  
     public ChangeableKind getChangeableKind() {
 795  0
         return theKindsObject;
 796  
     }
 797  
 
 798  
     /*
 799  
      * @see org.argouml.model.ModelImplementation#getAggregationKind()
 800  
      */
 801  
     public AggregationKind getAggregationKind() {
 802  6720
         return theKindsObject;
 803  
     }
 804  
 
 805  
     /*
 806  
      * @see org.argouml.model.ModelImplementation#getPseudostateKind()
 807  
      */
 808  
     public PseudostateKind getPseudostateKind() {
 809  349
         return theKindsObject;
 810  
     }
 811  
 
 812  
     /*
 813  
      * @see org.argouml.model.ModelImplementation#getScopeKind()
 814  
      */
 815  
     public ScopeKind getScopeKind() {
 816  0
         return theKindsObject;
 817  
     }
 818  
 
 819  
     /*
 820  
      * @see org.argouml.model.ModelImplementation#getConcurrencyKind()
 821  
      */
 822  
     public ConcurrencyKind getConcurrencyKind() {
 823  0
         return theKindsObject;
 824  
     }
 825  
 
 826  
     /*
 827  
      * @see org.argouml.model.ModelImplementation#getDirectionKind()
 828  
      */
 829  
     public DirectionKind getDirectionKind() {
 830  0
         return theKindsObject;
 831  
     }
 832  
 
 833  
     /*
 834  
      * @see org.argouml.model.ModelImplementation#getOrderingKind()
 835  
      */
 836  
     public OrderingKind getOrderingKind() {
 837  0
         return theKindsObject;
 838  
     }
 839  
 
 840  
 
 841  
     public VisibilityKind getVisibilityKind() {
 842  0
         return theKindsObject;
 843  
     }
 844  
 
 845  
     
 846  
     public XmiReader getXmiReader() throws UmlException {
 847  900
         XmiReader reader = new XmiReaderImpl(this);
 848  900
         return reader;
 849  
     }
 850  
 
 851  
 
 852  
     public XmiWriter getXmiWriter(Object model, OutputStream stream,
 853  
             String version) throws UmlException {
 854  0
         return new XmiWriterMDRImpl(this, model, stream, version);
 855  
     }
 856  
 
 857  
     /**
 858  
      * Return map of MOF ID to XmiReference (system id + xmi.id).
 859  
      *
 860  
      * @return the map
 861  
      */
 862  
     Map<String, XmiReference> getObjectToId() {
 863  2867
         return objectToId;
 864  
     }
 865  
 
 866  
     /**
 867  
      * Return map of maps keyed first by system id, then xmi.id with object as
 868  
      * value.
 869  
      * 
 870  
      * @return the map
 871  
      */
 872  
     Map<String, Map<String, Object>> getIdToObject() {
 873  900
         return idToObject;
 874  
     }
 875  
     
 876  
     /**
 877  
      * Remove an element from indexes mapping it back to its original xmi.id.
 878  
      * 
 879  
      * @param mofId MOF ID of element to be removed from indexes
 880  
      * @return false if no index entries were removed
 881  
      */
 882  
     boolean removeElement(String mofId) {
 883  2
         XmiReference xref = objectToId.remove(mofId);
 884  2
         if (xref != null) {
 885  0
             Map<String,Object> m = idToObject.get(xref.getSystemId());
 886  0
             if (m != null) {
 887  0
                 Object o = m.remove(xref.getXmiId());
 888  0
                 if (o != null) {
 889  0
                     if (!mofId.equals(((RefObject) o).refMofId())) {
 890  0
                         LOG.error("Internal index inconsistency for mof ID " 
 891  
                                 + mofId + " (got " + ((RefObject) o).refMofId());
 892  
                     }
 893  0
                     return true;
 894  
                 }
 895  
             }
 896  
         }
 897  
         // Elements created after file load won't have index entries
 898  2
         LOG.debug("Failed to remove index entries for mof ID " + mofId);
 899  2
         return false;
 900  
     }
 901  
     
 902  
     /**
 903  
      * Return map of MOF ID to XmiReference (system id + xmi.id).
 904  
      *
 905  
      * @return the map
 906  
      */
 907  
     Map<String, String> getPublic2SystemIds() {
 908  1800
         return public2SystemIds;
 909  
     }
 910  
 
 911  
     void addSearchPath(String path) {
 912  0
         searchDirs.add(path);
 913  0
     }
 914  
 
 915  
     void removeSearchPath(String path) {
 916  0
         searchDirs.remove(path);
 917  0
     }
 918  
 
 919  
     List<String> getSearchPath() {
 920  900
         return searchDirs;
 921  
     }
 922  
 
 923  
 }