Ptidej-v5.2-master/POM Tests/data/ArgoUML_0.28/src/org/argouml/notation/providers/uml/ClassifierRoleNotationUml.java
// $Id: ClassifierRoleNotationUml.java 16538 2009-01-07 07:32:45Z mvw $
// Copyright (c) 2006-2009 The Regents of the University of California. All
// Rights Reserved. Permission to use, copy, modify, and distribute this
// software and its documentation without fee, and without a written
// agreement is hereby granted, provided that the above copyright notice
// and this paragraph appear in all copies.  This software program and
// documentation are copyrighted by The Regents of the University of
// California. The software program and documentation are supplied "AS
// IS", without any accompanying services from The Regents. The Regents
// does not warrant that the operation of the program will be
// uninterrupted or error-free. The end-user understands that the program
// was developed for research purposes and is advised not to rely
// exclusively on the program for any reason.  IN NO EVENT SHALL THE
// UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
// SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS,
// ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
// THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
// SUCH DAMAGE. THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
// PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
// CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT,
// UPDATES, ENHANCEMENTS, OR MODIFICATIONS.

package org.argouml.notation.providers.uml;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;

import org.argouml.application.events.ArgoEventPump;
import org.argouml.application.events.ArgoEventTypes;
import org.argouml.application.events.ArgoHelpEvent;
import org.argouml.i18n.Translator;
import org.argouml.model.Model;
import org.argouml.notation.NotationSettings;
import org.argouml.notation.providers.ClassifierRoleNotation;
import org.argouml.util.MyTokenizer;

/**
 * The UML notation for a ClassifierRole. <p>
 * 
 * The following is supported: <p>
 * 
 * <pre>
 * baselist := [base] [, base]*
 * classifierRole := [name] [/ role] [: baselist]
 * </pre>
 *
 * The <code>role </code> and <code>baselist</code> can be given in
 * any order.<p>
 * 
 * The <code>name</code> is the Instance name, not used for a ClassifierRole.<p>
 *
 * This syntax is compatible with the UML 1.3 and 1.4 specification.
 * 
 * @author Michiel
 */
public class ClassifierRoleNotationUml extends ClassifierRoleNotation {


    /**
     * The Constructor.
     * 
     * @param classifierRole the UML ClassifierRole
     */
    public ClassifierRoleNotationUml(Object classifierRole) {
        super(classifierRole);
    }

    /*
     * @see org.argouml.notation.providers.NotationProvider#getParsingHelp()
     */
    public String getParsingHelp() {
        return "parsing.help.fig-classifierrole";
    }

    /*
     * @see org.argouml.notation.providers.NotationProvider#parse(java.lang.Object, java.lang.String)
     */
    public void parse(Object modelElement, String text) {
        try {
            parseClassifierRole(modelElement, text);
        } catch (ParseException pe) {
            String msg = "statusmsg.bar.error.parsing.classifierrole";
            Object[] args = {pe.getLocalizedMessage(),
                             Integer.valueOf(pe.getErrorOffset()), };
            ArgoEventPump.fireEvent(new ArgoHelpEvent(
                    ArgoEventTypes.HELP_CHANGED, this,
                    Translator.messageFormat(msg, args)));
        }
    }
    
    /**
     * Parses a ClassifierRole represented by the following line of the format:
     *
     * <pre>
     * baselist := [base] [, base]*
     * classifierRole := [name] [/ role] [: baselist]
     * </pre>
     *
     * <code>role </code> and <code>baselist</code> can be given in
     * any order.<p>
     *
     * This syntax is compatible with the UML 1.3 specification.
     *
     * (formerly: "name: base" )
     *
     * @param cls the classifier role to apply any changes to
     * @param s the String to parse
     * @return the classifier role with the applied changes
     * @throws ParseException when it detects an error in the attribute string. 
     *                  See also ParseError.getErrorOffset().
     */
    protected Object parseClassifierRole(Object cls, String s)
        throws ParseException {
        
        String name = null;
        String token;
        String role = null;
        String base = null;
        List<String> bases = null;
        boolean hasColon = false;
        boolean hasSlash = false;

        try {
            MyTokenizer st = new MyTokenizer(s, " ,\t,/,:,\\,");

            while (st.hasMoreTokens()) {
                token = st.nextToken();
                if (" ".equals(token) || "\t".equals(token)) {
                    /* Do nothing. */
                } else if ("/".equals(token)) {
                    hasSlash = true;
                    hasColon = false;

                    if (base != null) {
                        if (bases == null) {
                            bases = new ArrayList<String>();
                        }
                        bases.add(base);
                    }
                    base = null;
                } else if (":".equals(token)) {
                    hasColon = true;
                    hasSlash = false;

                    if (bases == null) {
                        bases = new ArrayList<String>();
                    }
                    if (base != null) {
                        bases.add(base);
                    }
                    base = null;
                } else if (",".equals(token)) {
                    if (base != null) {
                        if (bases == null) {
                            bases = new ArrayList<String>();
                        }
                        bases.add(base);
                    }
                    base = null;
                } else if (hasColon) {
                    if (base != null) {
                    	String msg = "parsing.error.classifier.extra-test";
                        throw new ParseException(
                                Translator.localize(msg), 
                                st.getTokenIndex());
                    }

                    base = token;
                } else if (hasSlash) {
                    if (role != null) {
                    	String msg = "parsing.error.classifier.extra-test";
                        throw new ParseException(
                                Translator.localize(msg), 
                                st.getTokenIndex());
                    }

                    role = token;
                } else {
                    if (name != null) {
                    	String msg = "parsing.error.classifier.extra-test";
                        throw new ParseException(
                                Translator.localize(msg), 
                                st.getTokenIndex());
                    }

                    name = token;
                }
            }
        } catch (NoSuchElementException nsee) {
            String msg = "parsing.error.classifier.unexpected-end-attribute";
            throw new ParseException(Translator.localize(msg), s.length());
        }

        if (base != null) {
            if (bases == null) {
                bases = new ArrayList<String>();
            }
            bases.add(base);
        }

        // TODO: What to do about object name???
        //    if (name != null)
        //      ;

        if (role != null) {
            Model.getCoreHelper().setName(cls, role.trim());
        }

        if (bases != null) {
            // Remove bases that aren't there anymore

            // copy - can't iterate modify live collection while iterating it
            Collection b = new ArrayList(Model.getFacade().getBases(cls));
            Iterator it = b.iterator();
            Object c;
            Object ns = Model.getFacade().getNamespace(cls);
            if (ns != null && Model.getFacade().getNamespace(ns) != null) {
                ns = Model.getFacade().getNamespace(ns);
            } else {
                ns = Model.getFacade().getModel(cls);
            }

            while (it.hasNext()) {
                c = it.next();
                if (!bases.contains(Model.getFacade().getName(c))) {
                    Model.getCollaborationsHelper().removeBase(cls, c);
                }
            }

            it = bases.iterator();
        addBases:
            while (it.hasNext()) {
                String d = ((String) it.next()).trim();

                Iterator it2 = b.iterator();
                while (it2.hasNext()) {
                    c = it2.next();
                    if (d.equals(Model.getFacade().getName(c))) {
                        continue addBases;
                    }
                }
                c = NotationUtilityUml.getType(d, ns);
                if (Model.getFacade().isACollaboration(
                        Model.getFacade().getNamespace(c))) {
                    Model.getCoreHelper().setNamespace(c, ns);
                }
                Model.getCollaborationsHelper().addBase(cls, c);
            }
        }
        
        return cls;
    }

    /*
     * @see org.argouml.notation.providers.NotationProvider#toString(java.lang.Object, java.util.Map)
     */
    @SuppressWarnings("deprecation")
    @Deprecated
    public String toString(Object modelElement, Map args) {
        return toString(modelElement);
    }

    private String toString(Object modelElement) {
        String nameString = Model.getFacade().getName(modelElement);
        if (nameString == null) { 
            nameString = "";
        }
        nameString = nameString.trim();
        // Loop through all base classes, building a comma separated list
        StringBuilder baseString = 
            formatNameList(Model.getFacade().getBases(modelElement));
        baseString = new StringBuilder(baseString.toString().trim());       
        // Build the final string
        if (nameString.length() != 0) {
            nameString = "/" + nameString;
        }
        if (baseString.length() != 0) {
            baseString = baseString.insert(0, ":");
        }
        return nameString + baseString.toString();
    }

    @Override
    public String toString(Object modelElement, NotationSettings settings) {
        return toString(modelElement);
    }

}
