Ptidej-v5.2-master/POM Tests/data/ArgoUML_0.28/src/org/argouml/notation/providers/uml/ObjectFlowStateStateNotationUml.java
// $Id: ObjectFlowStateStateNotationUml.java 16400 2008-12-21 16:27:58Z tfmorris $
// Copyright (c) 2006-2007 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.Map;
import java.util.Iterator;
import java.util.StringTokenizer;

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.kernel.ProjectManager;
import org.argouml.model.Model;
import org.argouml.notation.NotationSettings;
import org.argouml.notation.providers.ObjectFlowStateStateNotation;

/**
 * Notation for the State of an ObjectFlowState.
 * 
 * @author Michiel
 */
public class ObjectFlowStateStateNotationUml extends
        ObjectFlowStateStateNotation {

    /**
     * The constructor.
     *
     * @param objectflowstate
     *            the ObjectFlowState represented by this notation
     */
    public ObjectFlowStateStateNotationUml(Object objectflowstate) {
        super(objectflowstate);
    }
    
    /*
     * @see org.argouml.notation.providers.NotationProvider#getParsingHelp()
     */
    public String getParsingHelp() {
        return "parsing.help.fig-objectflowstate2";
    }

    /*
     * @see org.argouml.notation.providers.NotationProvider#parse(java.lang.Object, java.lang.String)
     */
    public void parse(Object modelElement, String text) {
        try {
            parseObjectFlowState2(modelElement, text);
        } catch (ParseException pe) {
            String msg = "statusmsg.bar.error.parsing.objectflowstate";
            Object[] args = {pe.getLocalizedMessage(),
                             Integer.valueOf(pe.getErrorOffset()), };
            ArgoEventPump.fireEvent(new ArgoHelpEvent(
                    ArgoEventTypes.HELP_CHANGED, this,
                    Translator.messageFormat(msg, args)));
        }
    }

    /**
     * Do the actual parsing.
     *
     * @param objectFlowState
     *            the given element to be altered
     * @param s
     *            the new string
     * @return the altered ObjectFlowState
     * @throws ParseException
     *             when the given text was rejected
     */
    protected Object parseObjectFlowState2(Object objectFlowState, String s)
        throws ParseException {
        s = s.trim();
        /* Let's not be picky about the brackets - just remove them: */
        if (s.startsWith("[")) {
            s = s.substring(1);
        }
        if (s.endsWith("]")) {
            s = s.substring(0, s.length() - 1);
        }
        s = s.trim();
        Object c = Model.getFacade().getType(objectFlowState); // get the
                                                                // classifier
        if (c != null) {
            if (Model.getFacade().isAClassifierInState(c)) {
                Object classifier = Model.getFacade().getType(c);
                if ((s == null) || "".equals(s)) {
                    // the State of a ClassifierInState is removed,
                    // so let's reduce it to a Classifier.
                    Model.getCoreHelper().setType(objectFlowState, classifier);
                    delete(c);
                    Model.getCoreHelper().setType(objectFlowState, classifier);
                    return objectFlowState; // the model is changed - job done
                }
                Collection states =
                    new ArrayList(Model.getFacade()
                        .getInStates(c));
                Collection statesToBeRemoved = new ArrayList(states);
                Collection namesToBeAdded = new ArrayList(); // Strings
                StringTokenizer tokenizer = new StringTokenizer(s, ",");
                while (tokenizer.hasMoreTokens()) {
                    String nextToken = tokenizer.nextToken().trim();
                    boolean found = false;
                    Iterator i = states.iterator();
                    while (i.hasNext()) {
                        Object state = i.next();
                        if (Model.getFacade().getName(state) == nextToken) {
                            found = true;
                            statesToBeRemoved.remove(state);
                        }
                    }
                    if (!found) {
                        namesToBeAdded.add(nextToken);
                    }
                }
                /* Remove the states that did not match. */
                states.removeAll(statesToBeRemoved);

                Iterator i = namesToBeAdded.iterator();
                while (i.hasNext()) {
                    String name = (String) i.next();
                    /*
                     * Now we have to see if any state in any statemachine of
                     * classifier is named [name]. If so, then we only have to
                     * link the state to c.
                     */
                    Object state =
                        Model.getActivityGraphsHelper()
                            .findStateByName(classifier, name);
                    if (state != null) {
                        states.add(state);
                        // the model is changed - our job is done
                    } else {
                        // no state named s is found, so we have to
                        // reject the user's input
                        String msg = 
                            "parsing.error.object-flow-state.state-not-found";
                        Object[] args = {s};
                        throw new ParseException(Translator.localize(msg, args),
                                0);
                    }
                }

                /* Finally, do the adaptations: */
                Model.getActivityGraphsHelper().setInStates(c, states);

            } else { // then c is a "normal" Classifier
                Collection statesToBeAdded = new ArrayList(); // UML states

                StringTokenizer tokenizer = new StringTokenizer(s, ",");
                while (tokenizer.hasMoreTokens()) {
                    String nextToken = tokenizer.nextToken().trim();
                    Object state =
                        Model.getActivityGraphsHelper()
                            .findStateByName(c, nextToken);
                    if (state != null) {
                        statesToBeAdded.add(state);
                    } else {
                        // no state with the given name is found, so we have to
                        // reject the complete user's input
                    	String msg = 
                    	    "parsing.error.object-flow-state.state-not-found";
                        Object[] args = {s};
                        throw new ParseException(Translator.localize(msg, args),
                                0);
                    }
                }

                // let's create a new ClassifierInState with the correct links
                Object cis =
                    Model.getActivityGraphsFactory()
                        .buildClassifierInState(c, statesToBeAdded);
                Model.getCoreHelper().setType(objectFlowState, cis);
                // the model is changed - our job is done
            }
        } else {
            // if no classifier has been set, then entering a state is
            // not useful, so the user's input has to be rejected.
            String msg = 
        	    "parsing.error.object-flow-state.classifier-not-found";
            throw new ParseException(Translator.localize(msg), 
                    0);
        }
        return objectFlowState;
    }

    /**
     * This deletes modelelements, and swallows null without barking.
     *
     * @author mvw@tigris.org
     * @param obj
     *            the modelelement to be deleted
     */
    private void delete(Object obj) {
        if (obj != null) {
            ProjectManager.getManager().getCurrentProject().moveToTrash(obj);
        }
    }

    /*
     * @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) {
        StringBuilder theNewText = new StringBuilder("");
        Object cis = Model.getFacade().getType(modelElement);
        if (Model.getFacade().isAClassifierInState(cis)) {
            theNewText.append("[ ");
            theNewText.append(formatNameList(
                    Model.getFacade().getInStates(cis)));
            theNewText.append(" ]");
        }
        return theNewText.toString();
    }

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