Ptidej-v5.2-master/POM Tests/data/ArgoUML_0.28/src/org/argouml/cognitive/ResolvedCritic.java
// $Id: ResolvedCritic.java 14751 2008-05-16 16:02:55Z tfmorris $
// Copyright (c) 2002-2008 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.cognitive;

import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;
import org.argouml.util.ItemUID;

// TODO: Maybe the exception strings should be internationalized

/**
 * This class is responsible for identifying one critic that has been resolved
 * by the user in one specific context.
 *
 * @author	Michael Stockman
 */
public class ResolvedCritic {
    /**
     * The logger.
     */
    private static final Logger LOG = Logger.getLogger(ResolvedCritic.class);

    /**
     * The name of the critic.
     */
    private String critic;

    /**
     * The IDs of the objects that define the context of the critic.
     */
    private List<String> offenders;


    /**
     * Create a new ResolvedCritic using the name of the Critic and the
     * List of objects that triggered the Critic given as parameters.
     *
     * @param   cr      The name of the Critic that has been resolved
     * @param   offs    The List of related objects.
     */
    public ResolvedCritic(String cr, List<String> offs) {
        critic = cr;
        if (offs != null) {
            offenders = new ArrayList<String>(offs);
        } else {
            offenders = new ArrayList<String>();
        }
    }
    
    /**
     * Same as {@link #ResolvedCritic(Critic,ListSet,boolean)}.
     *
     * @param c The Critic that has been resolved.
     * @param offs The set of objects that triggered the Critic.
     * @throws	UnresolvableException	If some of the objects does
     *			not have a ItemUID and does not accept a new
     *			one.
     */
    public ResolvedCritic(Critic c, ListSet offs)
    	throws UnresolvableException {

	this(c, offs, true);
    }

    /**
     * Creates a new ResolvedCritic from the given information.
     *
     * @param	c	The Critic that has been resolved.
     * @param	offs	The set of objects that triggered the Critic.
     * @param	canCreate	If it should try to assign new
     *				ItemUIDs to objects that doesn't have.
     * @throws	UnresolvableException	If some of the objects does
     *			not have a ItemUID and does not accept a new
     *			one.
     */
    public ResolvedCritic(Critic c, ListSet offs, boolean canCreate)
	throws UnresolvableException {
	if (c == null) {
	    throw new IllegalArgumentException();
	}

	//LOG.debug("Adding resolution for: " + c.getClass() + " " + canCreate);

	try {
	    if (offs != null && offs.size() > 0) {
		offenders = new ArrayList<String>(offs.size());
		importOffenders(offs, canCreate);
	    } else {
	        offenders = new ArrayList<String>();
	    }
	} catch (UnresolvableException ure) {
	    try {
		getCriticString(c);
	    } catch (UnresolvableException ure2) {
		throw new UnresolvableException(ure2.getMessage() + "\n"
						+ ure.getMessage());
	    }
	    throw ure;
	}

	critic = getCriticString(c);
    }

    /*
     * @see java.lang.Object#hashCode()
     *
     * This is a rather bad hash solution but with the {@link #equals(Object)}
     * defined as below, it is not possible to do better.
     */
    @Override
    public int hashCode() {
        if (critic == null) {
            return 0;
        }
        return critic.hashCode();
    }

    /**
     * equals returns true if and only if obj also is a ResolvedCritic,
     * has the same critic name, and has all related objects that this
     * object has. Note that it is not required that this object has all
     * related objects that that object has.<p>
     *
     * Formally that is inconsistent with {@link Object#equals(Object)
     * equals as specified in java.lang.Object},
     * but it was probably practical somehow.<p>
     *
     * The param obj is the Object to compare to.
     * Returns true if equal according to the description, false
     * otherwise.
     *
     * {@inheritDoc}
     */
    @Override
    public boolean equals(Object obj) {
	ResolvedCritic rc;

	if (obj == null || !(obj instanceof ResolvedCritic)) {
	    return false;
	}

	rc = (ResolvedCritic) obj;

	if (critic == null) {
	    if (rc.critic != null) {
	        return false;
	    }
	} else if (!critic.equals(rc.critic)) {
	    return false;
	}

	if (offenders == null) {
	    return true;
	}

	if (rc.offenders == null) {
	    return false;
	}

	for (String offender : offenders) {
	    if (offender == null) {
	        continue;
	    }

	    int j;
	    for (j = 0; j < rc.offenders.size(); j++) {
	        if (offender.equals(rc.offenders.get(j))) {
	            break;
	        }
	    }

	    if (j >= rc.offenders.size()) {
	        return false;
	    }
	}

	return true;
    }

    /**
     * Obtains a String that identifies the type of Critic.
     *
     * @param	c	A Critic.
     * @throws	UnresolvableException	Not implemented.
     * @return	A identifying name of the critic.
     */
    protected String getCriticString(Critic c) throws UnresolvableException {
        // TODO: Should throw if the string is not good?
        if (c == null) {
            throw (new UnresolvableException("Critic is null"));
        }
        String s = c.getClass().toString();
	return s;
    }

    /**
     * Imports the set of related objects in set to this object. If an
     * object does not have an ItemUID, canCreate determines if one will
     * be provided. If some object does not have an ItemUID and canCreate
     * is false or the object does not accept an ItemUID, then
     * UnresolvableException is thrown.
     *
     * @param	set	The set of related objects to import.
     * @param	canCreate	If ItemUIDs are allowed to be created.
     * @throws	UnresolvableException if not all objects can be
     *		imported.
     */
    protected void importOffenders(ListSet set, boolean canCreate)
	throws UnresolvableException {

	String fail = null;

        for (Object obj : set) {
	    String id = ItemUID.getIDOfObject(obj, canCreate);
	    if (id == null) {
		if (!canCreate) {
		    throw new UnresolvableException("ItemUID missing or "
						    + "unable to "
						    + "create for class: "
						    + obj.getClass());
		}

		if (fail == null) {
		    fail = obj.getClass().toString();
		} else {
		    fail = fail + ", " + obj.getClass().toString();
		}

		LOG.warn("Offender " + obj.getClass() + " unresolvable");

		// Use this for fast fail instead.
		// Sacrificed for complete fail. d00mst
		//throw new UnresolvableException(
		//	"Unable to create ItemUID for class: "
		//	+ obj.getClass());
	    } else {
	        offenders.add(id);
	    }
	}

	if (fail != null) {
	    throw new UnresolvableException("Unable to create ItemUID for "
					    + "some class(es): "
					    + fail);
	}
    }

    /**
     * Gets the content of critic.
     *
     * @return The critic this instance resolves.
     */
    public String getCritic() {
	return critic;
    }

    /**
     * Gets the list of related objects, offenders.
     *
     * @return The list of offenders of the critic this instance resolved.
     */
    public List<String> getOffenderList() {
	return offenders;
    }

    /*
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
	StringBuffer sb =
	    new StringBuffer("ResolvedCritic: " + critic + " : ");
	for (int i = 0; i < offenders.size(); i++) {
	    if (i > 0) {
	        sb.append(", ");
	    }
	    sb.append(offenders.get(i));
	}

	return sb.toString();
    }
}

