Coverage Report - org.argouml.notation.NotationProviderFactory2
 
Classes in this File Line Coverage Branch Coverage Complexity
NotationProviderFactory2
32%
18/55
20%
5/24
3.75
 
 1  
 /* $Id: NotationProviderFactory2.java 18852 2010-11-20 19:27:11Z mvw $
 2  
  *****************************************************************************
 3  
  * Copyright (c) 2009-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  
  *    Michiel van der Wulp
 11  
  *****************************************************************************
 12  
  *
 13  
  * Some portions of this file was previously release using the BSD License:
 14  
  */
 15  
 
 16  
 // Copyright (c) 2005-2009 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.notation;
 40  
 
 41  
 import java.lang.reflect.Constructor;
 42  
 import java.lang.reflect.InvocationTargetException;
 43  
 import java.util.HashMap;
 44  
 import java.util.Map;
 45  
 
 46  
 import org.apache.log4j.Logger;
 47  
 
 48  
 /**
 49  
  *  The NotationProviderFactory2 is a singleton, 
 50  
  *  since it is the accesspoint for all Figs 
 51  
  *  to access the textual representation of modelobjects, 
 52  
  *  and since plugin modules can add extra languages.
 53  
  *  
 54  
  * @author Michiel
 55  
  */
 56  
 public final class NotationProviderFactory2 {
 57  
 
 58  900
     private static final Logger LOG = 
 59  
         Logger.getLogger(NotationProviderFactory2.class);
 60  
 
 61  
     /**
 62  
      * TYPE_NAME the name of the modelelement, e.g. class, package, state
 63  
      */
 64  
     public static final int TYPE_NAME = 1;
 65  
 
 66  
     /**
 67  
      * TYPE_TRANSITION the main text shown above the transition.
 68  
      */
 69  
     public static final int TYPE_TRANSITION = 2;
 70  
 
 71  
     /**
 72  
      * TYPE_STATEBODY the multiline text shown inside the state body.
 73  
      */
 74  
     public static final int TYPE_STATEBODY = 3;
 75  
 
 76  
     /**
 77  
      * TYPE_ACTIONSTATE the text shown in an actionstate.
 78  
      */
 79  
     public static final int TYPE_ACTIONSTATE = 4;
 80  
 
 81  
     /**
 82  
      * TYPE_ATTRIBUTE the text shown in a attribute compartment (1 attrib only).
 83  
      */
 84  
     public static final int TYPE_ATTRIBUTE = 5;
 85  
 
 86  
     /**
 87  
      * TYPE_OPERATION the text shown in a operation compartment (1 oper only).
 88  
      */
 89  
     public static final int TYPE_OPERATION = 6;
 90  
 
 91  
     /**
 92  
      * TYPE_OBJECT the text shown on an object.
 93  
      */
 94  
     public static final int TYPE_OBJECT = 7;
 95  
 
 96  
     /**
 97  
      * TYPE_COMPONENTINSTANCE the text shown on a componentInstance.
 98  
      */
 99  
     public static final int TYPE_COMPONENTINSTANCE = 8;
 100  
 
 101  
     /**
 102  
      * TYPE_NODEINSTANCE the text shown on a componentInstance.
 103  
      */
 104  
     public static final int TYPE_NODEINSTANCE = 9;
 105  
     
 106  
     /**
 107  
      * TYPE_TYPE_OBJECTFLOWSTATE_TYPE the text shown on a 
 108  
      * objectflowstate's type, i.e. its classifier name.
 109  
      */
 110  
     public static final int TYPE_OBJECTFLOWSTATE_TYPE = 10;
 111  
 
 112  
     /**
 113  
      * TYPE_OBJECTFLOWSTATE_STATE the text shown on a 
 114  
      * objectflowstate's state.
 115  
      */
 116  
     public static final int TYPE_OBJECTFLOWSTATE_STATE = 11;
 117  
 
 118  
     /**
 119  
      * TYPE_CALLSTATE the text shown on a 
 120  
      * callstate's state.
 121  
      */
 122  
     public static final int TYPE_CALLSTATE = 12;
 123  
 
 124  
     /**
 125  
      * TYPE_CLASSIFIERROLE the text shown on a 
 126  
      * classifierrole.
 127  
      */
 128  
     public static final int TYPE_CLASSIFIERROLE = 13;
 129  
     
 130  
     /**
 131  
      * TYPE_MESSAGE the text shown on a Message 
 132  
      * in a Collaborations diagram.
 133  
      */
 134  
     public static final int TYPE_MESSAGE = 14;
 135  
 
 136  
     /**
 137  
      * TYPE_EXTENSION_POINT the text shown on a usecase
 138  
      * representing the extensionpoint.
 139  
      */
 140  
     public static final int TYPE_EXTENSION_POINT = 15;
 141  
 
 142  
     /**
 143  
      * The text shown at the association end that represents the role.
 144  
      */
 145  
     public static final int TYPE_ASSOCIATION_END_NAME = 16;
 146  
 
 147  
     /**
 148  
      * The text shown for the association role name.
 149  
      */
 150  
     public static final int TYPE_ASSOCIATION_ROLE = 17;
 151  
 
 152  
     /**
 153  
      * The text shown for the association role name.
 154  
      */
 155  
     public static final int TYPE_ASSOCIATION_NAME = 18;
 156  
 
 157  
     /**
 158  
      * The text shown for a multiplicity.
 159  
      */
 160  
     public static final int TYPE_MULTIPLICITY = 19;
 161  
 
 162  
     /**
 163  
      * The text shown for an enumeration literal.
 164  
      */
 165  
     public static final int TYPE_ENUMERATION_LITERAL = 20;
 166  
 
 167  
     /**
 168  
      * TYPE_MESSAGE the text shown on a Message 
 169  
      * in a Collaborations diagram.
 170  
      */
 171  
     public static final int TYPE_SD_MESSAGE = 21;
 172  
 
 173  
     /**
 174  
      * defaultLanguage the Notation language used by default, i.e. UML
 175  
      */
 176  
     private NotationName defaultLanguage;
 177  
 
 178  
     /**
 179  
      * allLanguages is a HashMap with as key the notationName,
 180  
      * and as value a second HashMap. This latter HashMap has as key the "type"
 181  
      * converted to Integer, and as value the provider (NotationProvider).
 182  
      */
 183  
     private Map<NotationName, Map<Integer, Class>> allLanguages;
 184  
 
 185  
     /**
 186  
      * The instance is the singleton.
 187  
      */
 188  
     private static NotationProviderFactory2 instance;
 189  
 
 190  
     /**
 191  
      * The constructor.
 192  
      */
 193  
     private NotationProviderFactory2() {
 194  900
         super();
 195  900
         allLanguages = new HashMap<NotationName, Map<Integer, Class>>();
 196  900
     }
 197  
 
 198  
     /**
 199  
      * @return returns the singleton instance
 200  
      */
 201  
     public static NotationProviderFactory2 getInstance() {
 202  4500
         if (instance == null) {
 203  900
             instance = new NotationProviderFactory2();
 204  
         }
 205  4500
         return instance;
 206  
     }
 207  
 
 208  
     /**
 209  
      * Get a NotationProvider for the current project.
 210  
      * <p>
 211  
      * If there is any reason for failure, null is returned - no
 212  
      * exception is thrown. 
 213  
      * The caller is supposed to deal with receiving null.
 214  
      * <p>
 215  
      * Use this function when you do not want to monitor model 
 216  
      * changes which may cause the string to change.
 217  
      * 
 218  
      * @param type the provider type
 219  
      * @param object the constructor parameter
 220  
      * @param name the name of the notation language to use
 221  
      * @return the provider, or null if there was any failure
 222  
      */
 223  
     public NotationProvider getNotationProvider(int type,
 224  
             Object object, NotationName name) {
 225  
 
 226  0
         Class clazz = getNotationProviderClass(type, name);
 227  0
         if (clazz != null) {
 228  
             try {
 229  0
                 Class[] cp = {Object.class};
 230  0
                 Constructor constructor = clazz.getConstructor(cp);
 231  0
                 Object[] params = {
 232  
                     object,
 233  
                 };
 234  0
                 return (NotationProvider) constructor.newInstance(params);
 235  0
             } catch (SecurityException e) {
 236  
                 // TODO: Why aren't we throwing an exception here?
 237  
                     // Returning null results in NPE and no explanation why.
 238  0
                 LOG.error("Exception caught", e);
 239  0
             } catch (NoSuchMethodException e) {
 240  
                 // TODO: Why aren't we throwing an exception here?
 241  
                     // Returning null results in NPE and no explanation why.
 242  0
                 LOG.error("Exception caught", e);
 243  0
             } catch (IllegalArgumentException e) {
 244  
                 // TODO: Why aren't we throwing an exception here?
 245  
                     // Returning null results in NPE and no explanation why.
 246  0
                 LOG.error("Exception caught", e);
 247  0
             } catch (InstantiationException e) {
 248  
                 // TODO: Why aren't we throwing an exception here?
 249  
                     // Returning null results in NPE and no explanation why.
 250  0
                 LOG.error("Exception caught", e);
 251  0
             } catch (IllegalAccessException e) {
 252  
                 // TODO: Why aren't we throwing an exception here?
 253  
                     // Returning null results in NPE and no explanation why.
 254  0
                 LOG.error("Exception caught", e);
 255  0
             } catch (InvocationTargetException e) {
 256  
                 // TODO: Why aren't we throwing an exception here?
 257  
                     // Returning null results in NPE and no explanation why.
 258  0
                 LOG.error("Exception caught", e);
 259  0
             }
 260  
         }
 261  0
         return null;
 262  
     }
 263  
 
 264  
     /**
 265  
      * Get a NotationProvider for the current project. 
 266  
      * This also initializes the listeners.
 267  
      * <p>
 268  
      * Use this function when you want to monitor model 
 269  
      * changes which may cause the string to change.
 270  
      * 
 271  
      * @param type the provider type
 272  
      * @param object the constructor parameter
 273  
      * @param nr the fig that refreshes after the NotationProvider has changed
 274  
      * @param name the name of the notation language to use
 275  
      * @return the provider
 276  
      */
 277  
     public NotationProvider getNotationProvider(int type,
 278  
             Object object, NotationRenderer nr, 
 279  
             NotationName name) {
 280  
 
 281  0
         NotationProvider p = getNotationProvider(type, object, name);
 282  0
         p.setRenderer(nr);
 283  0
         p.initialiseListener(object);
 284  0
         return p;
 285  
     }
 286  
 
 287  
     /**
 288  
      * This function looks for the requested notation provider type.
 289  
      * It is guaranteed to deliver:<ul>
 290  
      * <li>the requested type of the requested notation language,
 291  
      * <li>the requested type of the default notation, or
 292  
      * <li><code>null</code>.
 293  
      * </ul>
 294  
      *
 295  
      * @param type the provider type
 296  
      * @param name the context (i.e. the notation name)
 297  
      * @return the provider
 298  
      */
 299  
     private Class getNotationProviderClass(int type, NotationName name) {
 300  0
         if (allLanguages.containsKey(name)) {
 301  0
             Map<Integer, Class> t = allLanguages.get(name);
 302  0
             if (t.containsKey(Integer.valueOf(type))) {
 303  0
                 return t.get(Integer.valueOf(type));
 304  
             }
 305  
         }
 306  0
         Map<Integer, Class> t = allLanguages.get(defaultLanguage);
 307  0
         if (t != null && t.containsKey(Integer.valueOf(type))) {
 308  0
             return t.get(Integer.valueOf(type));
 309  
         }
 310  0
         return null;
 311  
     }
 312  
 
 313  
     /**
 314  
      * @param type the provider type
 315  
      * @param notationName the name of the notation (language)
 316  
      * @param provider the provider
 317  
      */
 318  
     public void addNotationProvider(int type,
 319  
             NotationName notationName, Class provider) {
 320  23400
         if (allLanguages.containsKey(notationName)) {
 321  21600
             Map<Integer, Class> t = allLanguages.get(notationName);
 322  21600
             t.put(Integer.valueOf(type), provider);
 323  21600
         } else {
 324  1800
             Map<Integer, Class> t = new HashMap<Integer, Class>();
 325  1800
             t.put(Integer.valueOf(type), provider);
 326  1800
             allLanguages.put(notationName, t);
 327  
         }
 328  23400
     }
 329  
 
 330  
     /**
 331  
      * @param notationName the UML notation that is to be used as default
 332  
      *                     if no other is found
 333  
      */
 334  
     public void setDefaultNotation(NotationName notationName) {
 335  900
         if (allLanguages.containsKey(notationName)) {
 336  900
             defaultLanguage = notationName;
 337  
         }
 338  900
     }
 339  
 
 340  
     /**
 341  
      * We need this to remove modules.
 342  
      *
 343  
      * @param notationName the notation to be removed
 344  
      * @return true if the notation was removed
 345  
      */
 346  
     public boolean removeNotation(NotationName notationName) {
 347  0
         if (defaultLanguage == notationName) {
 348  0
             return false;
 349  
         }
 350  0
         if (allLanguages.containsKey(notationName)) {
 351  0
             return allLanguages.remove(notationName) != null
 352  
                     && Notation.removeNotation(notationName);
 353  
         }
 354  0
         return false;
 355  
     }
 356  
 
 357  
 }