Coverage Report - org.argouml.kernel.ProfileConfiguration
 
Classes in this File Line Coverage Branch Coverage Complexity
ProfileConfiguration
46%
54/116
44%
30/68
2.87
ProfileConfiguration$1
11%
1/9
0%
0/4
2.87
 
 1  
 /* $Id: ProfileConfiguration.java 17822 2010-01-12 18:47:46Z linus $
 2  
  *****************************************************************************
 3  
  * Copyright (c) 2009 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  
  *    thn
 11  
  *****************************************************************************
 12  
  *
 13  
  * Some portions of this file was previously release using the BSD License:
 14  
  */
 15  
 
 16  
 // Copyright (c) 2007 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.kernel;
 40  
 
 41  
 import java.awt.Image;
 42  
 import java.beans.PropertyChangeEvent;
 43  
 import java.util.ArrayList;
 44  
 import java.util.Collection;
 45  
 import java.util.HashSet;
 46  
 import java.util.Iterator;
 47  
 import java.util.List;
 48  
 import java.util.Set;
 49  
 
 50  
 import org.apache.log4j.Logger;
 51  
 import org.argouml.application.events.ArgoEventPump;
 52  
 import org.argouml.application.events.ArgoEventTypes;
 53  
 import org.argouml.application.events.ArgoProfileEvent;
 54  
 import org.argouml.configuration.Configuration;
 55  
 import org.argouml.configuration.ConfigurationKey;
 56  
 import org.argouml.model.Model;
 57  
 import org.argouml.profile.DefaultTypeStrategy;
 58  
 import org.argouml.profile.FigNodeStrategy;
 59  
 import org.argouml.profile.FormatingStrategy;
 60  
 import org.argouml.profile.Profile;
 61  
 import org.argouml.profile.ProfileException;
 62  
 import org.argouml.profile.ProfileFacade;
 63  
 
 64  
 /**
 65  
  *   This class captures represents the unique access point for the 
 66  
  *   configurability allowed by the use of profiles. 
 67  
  *
 68  
  *   @author maurelio1234
 69  
  */
 70  0
 public class ProfileConfiguration extends AbstractProjectMember {
 71  
     /**
 72  
      * Logger.
 73  
      */
 74  900
     private static final Logger LOG = Logger
 75  
             .getLogger(ProfileConfiguration.class);
 76  
 
 77  
     private FormatingStrategy formatingStrategy;
 78  
 
 79  
     private DefaultTypeStrategy defaultTypeStrategy;
 80  
 
 81  968
     private List figNodeStrategies = new ArrayList();
 82  
 
 83  968
     private List<Profile> profiles = new ArrayList<Profile>();
 84  
 
 85  968
     private List<Object> profileModels = new ArrayList<Object>();
 86  
     
 87  
     /**
 88  
      * The extension used in serialization and returned by {@link #getType()}
 89  
      */
 90  
     public static final String EXTENSION = "profile";
 91  
     
 92  
 
 93  
     /**
 94  
      * The configuration key for the default stereotype view.
 95  
      */
 96  900
     public static final ConfigurationKey KEY_DEFAULT_STEREOTYPE_VIEW = 
 97  
         Configuration.makeKey("profiles", "stereotypeView");
 98  
     
 99  
     /**
 100  
      * The default constructor for this class. Sets the default profiles as 
 101  
      * given by {@link org.argouml.profile.ProfileManager} as the profiles of 
 102  
      * the project.
 103  
      * 
 104  
      * @param project the project that contains this configuration
 105  
      */
 106  
     public ProfileConfiguration(Project project) {
 107  968
         super(EXTENSION, project);
 108  968
         List c = project.getUserDefinedModelList();
 109  968
         Object m = c.isEmpty() ? null : c.get(0);
 110  968
         if (project.getProjectType() != Project.PROFILE_PROJECT) {
 111  
             // a profile initially has no applied profiles, we go bottom-up
 112  954
             for (Profile p : ProfileFacade.getManager().getDefaultProfiles()) {
 113  2862
                 addProfile(p, m);
 114  
             }
 115  
         }
 116  
 
 117  968
         updateStrategies();
 118  968
     }
 119  
     
 120  
     /**
 121  
      * The constructor for pre-defined profile configurations, such as when a 
 122  
      * project is read from a saved file.
 123  
      * @param project the project that contains this configuration
 124  
      * @param configuredProfiles the {@link Profile}s that will be the project 
 125  
      *        profiles
 126  
      */
 127  
     public ProfileConfiguration(Project project, 
 128  
             Collection<Profile> configuredProfiles) {
 129  0
         super(EXTENSION, project);
 130  0
         List c = project.getUserDefinedModelList();
 131  0
         Object m = c.isEmpty() ? null : c.get(0);
 132  0
         for (Profile profile : configuredProfiles) {
 133  0
             addProfile(profile, m);
 134  
         }
 135  0
         updateStrategies();
 136  0
     }
 137  
     
 138  
     private void updateStrategies() {
 139  3830
         for (Profile profile : profiles) {
 140  8586
             activateFormatingStrategy(profile);                
 141  8586
             activateDefaultTypeStrategy(profile);                
 142  
         }
 143  3830
     }
 144  
 
 145  
     /**
 146  
      * @return the current formating strategy
 147  
      */
 148  
     public FormatingStrategy getFormatingStrategy() {
 149  0
         return formatingStrategy;
 150  
     }
 151  
 
 152  
     /**
 153  
      * @return the current default type strategy
 154  
      */
 155  
     public DefaultTypeStrategy getDefaultTypeStrategy() {
 156  0
         return defaultTypeStrategy;
 157  
     }
 158  
     
 159  
     /**
 160  
      * Updates the current strategy to the strategy provided by the 
 161  
      * passed profile. The profile should have been previously registered.
 162  
      * 
 163  
      * @param profile the profile providing the current default type strategy
 164  
      */
 165  
     public void activateDefaultTypeStrategy(Profile profile) {
 166  8586
         if (profile != null && profile.getDefaultTypeStrategy() != null
 167  
                 && getProfiles().contains(profile)) {
 168  3816
             this.defaultTypeStrategy = profile.getDefaultTypeStrategy();
 169  
         }
 170  8586
     }
 171  
     
 172  
     /**
 173  
      * Updates the current strategy to the strategy provided by the 
 174  
      * passed profile. The profile should have been previously registered.
 175  
      * 
 176  
      * @param profile the profile providing the current formating strategy
 177  
      */
 178  
     public void activateFormatingStrategy(Profile profile) {
 179  8586
         if (profile != null && profile.getFormatingStrategy() != null
 180  
                 && getProfiles().contains(profile)) {
 181  3816
             this.formatingStrategy = profile.getFormatingStrategy();
 182  
         }
 183  8586
     }
 184  
 
 185  
     /**
 186  
      * @return the list of applied profiles
 187  
      */
 188  
     public List<Profile> getProfiles() {
 189  13752
         return profiles;
 190  
     }
 191  
 
 192  
     /**
 193  
      * Applies a new profile to this configuration.
 194  
      * 
 195  
      * @param p the profile to be applied
 196  
      * @deprecated for 0.29.2, because since UML2 a profile must be applied to
 197  
      * a model
 198  
      */
 199  
     @Deprecated
 200  
     public void addProfile(Profile p) {
 201  0
         addProfile(p, null);
 202  0
     }
 203  
 
 204  
     /**
 205  
      * Applies a new profile to this configuration and to the given model (or
 206  
      * other profile, which could be later a collection).
 207  
      * 
 208  
      * @param p the profile to be applied
 209  
      * @param m the model (or profile) to which the profile will be applied
 210  
      */
 211  
     @SuppressWarnings("unchecked")
 212  
     public void addProfile(Profile p, Object m) {
 213  3816
         if (!profiles.contains(p)) {
 214  2862
             profiles.add(p);
 215  
             try {
 216  2862
                 for (Object profile : p.getProfilePackages()) {
 217  954
                     Model.getExtensionMechanismsHelper().applyProfile(m, profile);
 218  
                 }
 219  2862
                 profileModels.addAll(p.getProfilePackages());
 220  0
             } catch (ProfileException e) {
 221  0
                 LOG.warn("Error retrieving profile's " + p + " packages.", e);
 222  2862
             }
 223  
             
 224  2862
             FigNodeStrategy fns = p.getFigureStrategy();
 225  2862
             if (fns != null) {
 226  0
                 figNodeStrategies.add(fns);
 227  
             }
 228  
 
 229  2862
             for (Profile dependency : p.getDependencies()) {
 230  954
                 addProfile(dependency, m);
 231  
             }
 232  
 
 233  2862
             updateStrategies();
 234  2862
             ArgoEventPump.fireEvent(new ArgoProfileEvent(
 235  
                     ArgoEventTypes.PROFILE_ADDED, new PropertyChangeEvent(this,
 236  
                             "profile", null, p)));
 237  
         }
 238  3816
     }
 239  
         
 240  
     /**
 241  
      * @return the list of models of the currently applied profile.
 242  
      */
 243  
     private List getProfileModels() {
 244  56
         return profileModels;
 245  
     }
 246  
 
 247  
     /**
 248  
      * Removes the passed profile from this configuration.
 249  
      * 
 250  
      * @param p the profile to be applied
 251  
      * @deprecated for 0.29.2, because since UML2 a profile must be unapplied
 252  
      * from a model
 253  
      */
 254  
     @Deprecated
 255  
     public void removeProfile(Profile p) {
 256  0
         removeProfile(p, null);
 257  0
     }
 258  
 
 259  
     /**
 260  
      * Removes the passed profile from the configuration and unapplies it from
 261  
      * the given model (or other profile, which could be later a collection).
 262  
      * 
 263  
      * @param p the profile to be removed/unapplied
 264  
      * @param m the model (or profile) to which the profile will be unapplied
 265  
      */
 266  
     public void removeProfile(Profile p, Object m) {
 267  0
         profiles.remove(p);
 268  
         try {
 269  0
             for (Object profile : p.getProfilePackages()) {
 270  0
                 Model.getExtensionMechanismsHelper().unapplyProfile(m, profile);
 271  
             }
 272  0
             profileModels.removeAll(p.getProfilePackages());
 273  0
         } catch (ProfileException e) {
 274  0
             LOG.error("Exception", e);
 275  0
         }
 276  
 
 277  0
         FigNodeStrategy fns = p.getFigureStrategy();
 278  0
         if (fns != null) {
 279  0
             figNodeStrategies.remove(fns);
 280  
         }
 281  
 
 282  0
         if (formatingStrategy == p.getFormatingStrategy()) {
 283  0
             formatingStrategy = null;
 284  
         }
 285  
 
 286  0
         List<Profile> markForRemoval = new ArrayList<Profile>();
 287  0
         for (Profile profile : profiles) {
 288  0
             if (profile.getDependencies().contains(p)) {
 289  0
                 markForRemoval.add(profile);
 290  
             }
 291  
         }
 292  
 
 293  0
         for (Profile profile : markForRemoval) {
 294  0
             removeProfile(profile, m);
 295  
         }
 296  
 
 297  0
         updateStrategies();
 298  0
         ArgoEventPump.fireEvent(new ArgoProfileEvent(
 299  
                 ArgoEventTypes.PROFILE_REMOVED, new PropertyChangeEvent(this,
 300  
                         "profile", p, null)));
 301  0
     }
 302  
     
 303  968
     private FigNodeStrategy compositeFigNodeStrategy = new FigNodeStrategy() {
 304  
 
 305  
         public Image getIconForStereotype(Object element) {
 306  0
             Iterator it = figNodeStrategies.iterator();
 307  
 
 308  0
             while (it.hasNext()) {
 309  0
                 FigNodeStrategy strat = (FigNodeStrategy) it.next();
 310  0
                 Image extra = strat.getIconForStereotype(element);
 311  
 
 312  0
                 if (extra != null) {
 313  0
                     return extra;
 314  
                 }
 315  0
             }
 316  0
             return null;
 317  
         }
 318  
         
 319  
     };
 320  
     
 321  
     /**
 322  
      * @return the current FigNodeStrategy
 323  
      */
 324  
     public FigNodeStrategy getFigNodeStrategy() {
 325  0
         return compositeFigNodeStrategy; 
 326  
     }
 327  
 
 328  
     /**
 329  
      * @return the extension for this project member
 330  
      * @see org.argouml.kernel.AbstractProjectMember#getType()
 331  
      */
 332  
     public String getType() {
 333  968
         return EXTENSION;
 334  
     }
 335  
 
 336  
     /**
 337  
      * Objects of this class are always consistent, there's no need 
 338  
      * to repair them.
 339  
      * 
 340  
      * @return the empty string.
 341  
      * @see org.argouml.kernel.ProjectMember#repair()
 342  
      */
 343  
     public String repair() {
 344  0
         return "";
 345  
     }
 346  
 
 347  
     /**
 348  
      * @return the "Profile Configuration" string
 349  
      * @see java.lang.Object#toString()
 350  
      */
 351  
     @Override
 352  
     public String toString() {
 353  8922
         return "Profile Configuration";
 354  
     }
 355  
 
 356  
 
 357  
     /**
 358  
      * Find a stereotype with the given name which is applicable to the given 
 359  
      * element.
 360  
      * 
 361  
      * @param name name of stereotype to look for
 362  
      * @param element model element to which the stereotype must be applicable
 363  
      * @return the stereotype or null if none found
 364  
      */
 365  
     public Object findStereotypeForObject(String name, Object element) {
 366  0
         Iterator iter = null;
 367  
         
 368  0
         for (Object model : profileModels) {
 369  0
             iter = Model.getFacade().getOwnedElements(model).iterator();
 370  
 
 371  0
             while (iter.hasNext()) {
 372  0
                 Object stereo = iter.next();
 373  0
                 if (!Model.getFacade().isAStereotype(stereo)
 374  
                         || !name.equals(Model.getFacade().getName(stereo))) {
 375  0
                     continue;
 376  
                 }
 377  
 
 378  0
                 if (Model.getExtensionMechanismsHelper().isValidStereotype(
 379  
                         element, stereo)) {
 380  0
                     return stereo;
 381  
                 }
 382  0
             }
 383  
         }
 384  
 
 385  0
         return null;
 386  
     }
 387  
 
 388  
     /**
 389  
      * Search for the given type in all of the profile models.
 390  
      * 
 391  
      * @param name name of type to be found
 392  
      * @return the type or null
 393  
      */
 394  
     public Object findType(String name) {
 395  56
         for (Object model : getProfileModels()) {
 396  56
             Object result = findTypeInModel(name, model);
 397  56
             if (result != null) {
 398  0
                 return result;
 399  
             }
 400  56
         }
 401  56
         return null;
 402  
     }
 403  
 
 404  
     /**
 405  
      * Finds a type in a model by name
 406  
      * 
 407  
      * FIXME: duplicated from the method with the same name in 
 408  
      * org.argouml.profile.internal.ModelUtils.
 409  
      * 
 410  
      * @param s the type name
 411  
      * @param model the model
 412  
      * @return the type or <code>null</code> if the type has not been found.
 413  
      */
 414  
     public static Object findTypeInModel(String s, Object model) {
 415  
 
 416  56
         if (!Model.getFacade().isANamespace(model)) {
 417  0
             throw new IllegalArgumentException(
 418  
                     "Looking for the classifier " + s
 419  
                     + " in a non-namespace object of " + model
 420  
                     + ". A namespace was expected.");
 421  
         }
 422  
 
 423  56
         Collection allClassifiers =
 424  
             Model.getModelManagementHelper()
 425  
                 .getAllModelElementsOfKind(model,
 426  
                         Model.getMetaTypes().getClassifier());
 427  
 
 428  56
         Object[] classifiers = allClassifiers.toArray();
 429  56
         Object classifier = null;
 430  
 
 431  280
         for (int i = 0; i < classifiers.length; i++) {
 432  
 
 433  224
             classifier = classifiers[i];
 434  224
             if (Model.getFacade().getName(classifier) != null
 435  
                         && Model.getFacade().getName(classifier).equals(s)) {
 436  0
                 return classifier;
 437  
             }
 438  
         }
 439  
 
 440  56
         return null;
 441  
     }
 442  
 
 443  
     /**
 444  
      * Find all the model elements in the configured {@link Profile}s 
 445  
      * of the given meta type.
 446  
      * 
 447  
      * @param metaType the meta type of the model elements to find
 448  
      * @return a {@link Collection} containing the model elements that 
 449  
      *         are of the given meta type
 450  
      */
 451  
     @SuppressWarnings("unchecked")
 452  
     public Collection findByMetaType(Object metaType) {
 453  0
         Set elements = new HashSet();
 454  
 
 455  0
         Iterator it = getProfileModels().iterator();
 456  0
         while (it.hasNext()) {
 457  0
             Object model = it.next();
 458  0
             elements.addAll(Model.getModelManagementHelper()
 459  
                     .getAllModelElementsOfKind(model, metaType));
 460  0
         }
 461  0
         return elements;
 462  
     }
 463  
 
 464  
     /**
 465  
      * @param modelElement
 466  
      *                ModelElement for which find possible stereotypes
 467  
      * @return collection of stereotypes which are valid for the given model
 468  
      *         element.
 469  
      */
 470  
     public Collection findAllStereotypesForModelElement(Object modelElement) {
 471  0
         return Model.getExtensionMechanismsHelper().getAllPossibleStereotypes(
 472  
                 getProfileModels(), modelElement);
 473  
     }
 474  
 }