Ptidej-v5.2-master/POM Tests/data/ArgoUML_0.28/src/org/argouml/profile/internal/ProfileUML.java
// $Id: ProfileUML.java 15925 2008-10-14 19:29:18Z tfmorris $
// Copyright (c) 1996-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.profile.internal;

import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

import org.argouml.cognitive.Critic;
import org.argouml.cognitive.ToDoItem;
import org.argouml.model.Model;
import org.argouml.profile.CoreProfileReference;
import org.argouml.profile.DefaultTypeStrategy;
import org.argouml.profile.FormatingStrategy;
import org.argouml.profile.Profile;
import org.argouml.profile.ProfileException;
import org.argouml.profile.ProfileModelLoader;
import org.argouml.profile.ProfileReference;
import org.argouml.profile.ResourceModelLoader;
import org.argouml.profile.internal.ocl.CrOCL;
import org.argouml.profile.internal.ocl.InvalidOclException;
import org.argouml.uml.cognitive.critics.CrAssocNameConflict;
import org.argouml.uml.cognitive.critics.CrAttrNameConflict;
import org.argouml.uml.cognitive.critics.CrCircularAssocClass;
import org.argouml.uml.cognitive.critics.CrCircularInheritance;
import org.argouml.uml.cognitive.critics.CrClassMustBeAbstract;
import org.argouml.uml.cognitive.critics.CrCrossNamespaceAssoc;
import org.argouml.uml.cognitive.critics.CrDupParamName;
import org.argouml.uml.cognitive.critics.CrDupRoleNames;
import org.argouml.uml.cognitive.critics.CrFinalSubclassed;
import org.argouml.uml.cognitive.critics.CrForkOutgoingTransition;
import org.argouml.uml.cognitive.critics.CrIllegalGeneralization;
import org.argouml.uml.cognitive.critics.CrInterfaceAllPublic;
import org.argouml.uml.cognitive.critics.CrInterfaceOperOnly;
import org.argouml.uml.cognitive.critics.CrInvalidBranch;
import org.argouml.uml.cognitive.critics.CrInvalidFork;
import org.argouml.uml.cognitive.critics.CrInvalidHistory;
import org.argouml.uml.cognitive.critics.CrInvalidInitial;
import org.argouml.uml.cognitive.critics.CrInvalidJoin;
import org.argouml.uml.cognitive.critics.CrInvalidJoinTriggerOrGuard;
import org.argouml.uml.cognitive.critics.CrInvalidPseudoStateTrigger;
import org.argouml.uml.cognitive.critics.CrInvalidSynch;
import org.argouml.uml.cognitive.critics.CrJoinIncomingTransition;
import org.argouml.uml.cognitive.critics.CrMultiComposite;
import org.argouml.uml.cognitive.critics.CrMultipleAgg;
import org.argouml.uml.cognitive.critics.CrMultipleDeepHistoryStates;
import org.argouml.uml.cognitive.critics.CrMultipleShallowHistoryStates;
import org.argouml.uml.cognitive.critics.CrNWayAgg;
import org.argouml.uml.cognitive.critics.CrNameConflict;
import org.argouml.uml.cognitive.critics.CrNameConflictAC;
import org.argouml.uml.cognitive.critics.CrNameConfusion;
import org.argouml.uml.cognitive.critics.CrOppEndConflict;
import org.argouml.uml.cognitive.critics.CrOppEndVsAttr;

/**
 * This class represents the default UML profile
 *
 * @author maurelio1234
 */
public class ProfileUML extends Profile {
    
    private static final String PROFILE_FILE = "default-uml14.xmi";

    static final String NAME = "UML 1.4";
    
    private FormatingStrategy formatingStrategy;
    private ProfileModelLoader profileModelLoader;
    private Collection model;
        
    /**
     * Construct a Profile for UML modeling. 
     * @throws ProfileException 
     */
    @SuppressWarnings("unchecked")
    ProfileUML() throws ProfileException {
        formatingStrategy = new JavaFormatingStrategy();
        profileModelLoader = new ResourceModelLoader();
        ProfileReference profileReference = null;
        try {
            profileReference = new CoreProfileReference(PROFILE_FILE);
        } catch (MalformedURLException e) {
            throw new ProfileException(
                "Exception while creating profile reference.", e);
        }
        model = profileModelLoader.loadModel(profileReference);

        if (model == null) {
            model = new ArrayList();
            model.add(Model.getModelManagementFactory().createModel());
        }
        
        loadWellFormednessRules();
    }    

    private void loadWellFormednessRules() {
        Set<Critic> critics = new HashSet<Critic>();
        
        critics.add(new CrAssocNameConflict());
        critics.add(new CrAttrNameConflict());
        critics.add(new CrCircularAssocClass());
        critics.add(new CrCircularInheritance());
        critics.add(new CrClassMustBeAbstract());
        critics.add(new CrCrossNamespaceAssoc());
        critics.add(new CrDupParamName());
        critics.add(new CrDupRoleNames());
        critics.add(new CrNameConfusion());

        critics.add(new CrInvalidHistory());
        critics.add(new CrInvalidSynch());
        critics.add(new CrInvalidJoinTriggerOrGuard());
        critics.add(new CrInvalidPseudoStateTrigger());
        critics.add(new CrInvalidInitial());
        
        critics.add(new CrInvalidJoin());
        critics.add(new CrInvalidFork());
        critics.add(new CrInvalidBranch());

        critics.add(new CrMultipleDeepHistoryStates());
        critics.add(new CrMultipleShallowHistoryStates());
        critics.add(new CrForkOutgoingTransition());
        critics.add(new CrJoinIncomingTransition());

        critics.add(new CrFinalSubclassed());
        critics.add(new CrIllegalGeneralization());
        critics.add(new CrInterfaceAllPublic());
        critics.add(new CrInterfaceOperOnly());
        critics.add(new CrMultipleAgg());
        critics.add(new CrNWayAgg());
        critics.add(new CrNameConflictAC());
        
        critics.add(new CrOppEndConflict());
        critics.add(new CrMultiComposite());
        critics.add(new CrNameConflict());
        critics.add(new CrOppEndVsAttr());

        // Missing WFRs
        
        // Association Class
        // 4.5.3.2 [1]
        
        try {
            critics.add(new CrOCL("context AssociationClass inv:"
                    + "self.allConnections->"
                    + "forAll( ar | self.allFeatures->"
                    + "forAll( f | f.oclIsKindOf(StructuralFeature) "
                    + "implies ar.name <> f.name ))",
                    "The names of the AssociationEnds and "
                            + "the StructuralFeatures do not overlap.", null,
                    ToDoItem.HIGH_PRIORITY, null, null, "http://www.uml.org/"));
        } catch (InvalidOclException e) {
            e.printStackTrace();
        }
        
        // 4.5.3.2 [2]
        
        try {
            critics.add(new CrOCL("context AssociationClass inv:"
                    + "self.allConnections->"
                    + "forAll(ar | ar.participant <> self)",

                    "An AssociationClass cannot be defined "
                    + "between itself and something else.", null,
                    ToDoItem.HIGH_PRIORITY, null, null, "http://www.uml.org/"));
        } catch (InvalidOclException e) {
            e.printStackTrace();
        }
        
        // Behavioral Feature
        // 4.5.3.5 [2]

        // it works, but a bug in namespace.contents prevents it from 
        // working when the type of the parameter comes from a profile         
//        try {
//            Agency.register(new CrOCL("context BehavioralFeature inv:"
//                    + "self.parameter->"
//                    + "forAll( p | self.owner.namespace.allContents->"
//                    + "includes (p.type) )",
//                    "The type of the Parameters should be "
//                            + "included in the Namespace of the Classifier.",
//                    null, ToDoItem.HIGH_PRIORITY, null, null,
//                    "http://www.uml.org/"));
//        } catch (InvalidOclException e) {
//            e.printStackTrace();
//        }
        
        // Classfier
        // 4.5.3.8 [5]
        try {
            critics.add(new CrOCL("context Classifier inv:"
                    + "self.oppositeAssociationEnds->" 
                    + "forAll( o | not self.allAttributes->" 
                    + "union (self.allContents)->" 
                    + "collect ( q | q.name )->includes (o.name) )",
            "The name of an opposite AssociationEnd may not be the same "
          + "as the name of an Attribute or a ModelElement contained "
          + "in the Classifier.", null,
                    ToDoItem.HIGH_PRIORITY, null, null, "http://www.uml.org/"));
        } catch (InvalidOclException e) {
            e.printStackTrace();
        }

        // DataType
        // 4.5.3.12 [1]
        try {
            critics.add(new CrOCL("context DataType inv:"
                    + "self.allFeatures->forAll(f | f.oclIsKindOf(Operation)"
                    + " and f.oclAsType(Operation).isQuery)",
                    "A DataType can only contain Operations, "
                            + "which all must be queries.", null,
                    ToDoItem.HIGH_PRIORITY, null, null, "http://www.uml.org/"));
        } catch (InvalidOclException e) {
            e.printStackTrace();
        }

        // GeneralizableElement
        // 4.5.3.20 [1]
        try {
            critics.add(new CrOCL("context GeneralizableElement inv:"
                    + "self.isRoot implies self.generalization->isEmpty",
                    "A root cannot have any Generalizations.", null,
                    ToDoItem.HIGH_PRIORITY, null, null, "http://www.uml.org/"));
        } catch (InvalidOclException e) {
            e.printStackTrace();
        }

        // 4.5.3.20 [4]
        try {
            critics.add(new CrOCL("context GeneralizableElement inv:"
                    + "self.generalization->"
                    + "forAll(g |self.namespace.allContents->"
                    + "includes(g.parent) )",
                    "The parent must be included in the Namespace of"
                            + " the GeneralizableElement.", null,
                    ToDoItem.HIGH_PRIORITY, null, null, "http://www.uml.org/"));
        } catch (InvalidOclException e) {
            e.printStackTrace();
        }
 
        // Namespace
        // 4.5.3.26 [2]
        try {
            critics.add(new CrOCL("context Namespace inv:"
                    + "self.allContents -> select(x|x.oclIsKindOf(Association))->"
                    + "forAll(a1, a2 |a1.name = a2.name and "
                    + "a1.connection.participant = a2.connection.participant"
                    + " implies a1 = a2)",
                    "All Associations must have a unique combination of name "
                            + "and associated Classifiers in the Namespace.",
                    null, ToDoItem.HIGH_PRIORITY, null, null,
                    "http://www.uml.org/"));
        } catch (InvalidOclException e) {
            e.printStackTrace();
        }        
        
        setCritics(critics);
    }

    @Override
    public FormatingStrategy getFormatingStrategy() {
        return formatingStrategy;
    }

    @Override
    public String getDisplayName() {
        return NAME;
    }


    @Override
    public Collection getProfilePackages() {
        return model;
    }
    

    @Override
    public DefaultTypeStrategy getDefaultTypeStrategy() {
        return new DefaultTypeStrategy() {
            public Object getDefaultAttributeType() {
                return ModelUtils.findTypeInModel("Integer", model.iterator()
                        .next());
            }

            public Object getDefaultParameterType() {
                return ModelUtils.findTypeInModel("Integer", model.iterator()
                        .next());
            }

            public Object getDefaultReturnType() {
                return null;
            }

        };
    }
}
