|
What this is
Other links
The source code// $Id: Critic.java,v 1.38 2004/09/05 10:32:51 mvw Exp $ // Copyright (c) 1996-2004 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. // File: Critic.java // Classes: Critic // Original Author: jrobbins@ics.uci.edu // $Id: Critic.java,v 1.38 2004/09/05 10:32:51 mvw Exp $ package org.argouml.cognitive.critics; import java.io.Serializable; import java.util.Enumeration; import java.util.Hashtable; import java.util.Vector; import javax.swing.Icon; import org.apache.log4j.Logger; import org.argouml.application.api.Configuration; import org.argouml.application.api.ConfigurationKey; import org.argouml.application.helpers.ResourceLoaderWrapper; import org.argouml.cognitive.Decision; import org.argouml.cognitive.DesignMaterial; import org.argouml.cognitive.Designer; import org.argouml.cognitive.Goal; import org.argouml.cognitive.Poster; import org.argouml.cognitive.ToDoItem; import org.argouml.i18n.Translator; import org.argouml.kernel.Wizard; import org.tigris.gef.util.VectorSet; /** "Abstract" base class for design critics. Each subclass should define * its own predicate method and define its own relevance tags.
* * By default this method basically asks the critic to again * critique the offending Object and then it checks if the * resulting ToDoItem is the same as the one already posted. This is * simple and it works fine for light-weight critics. Critics that * expend a lot of computational effort in making feedback that can * be easily check to see if it still holds, should override this * method.
*
* TODO: Maybe ToDoItem should carry some data to make
* this method more efficient.
*
* @see org.argouml.cognitive.Poster#stillValid(
* org.argouml.cognitive.ToDoItem, org.argouml.cognitive.Designer)
*/
public boolean stillValid(ToDoItem i, Designer dsgr) {
if (!isActive()) {
LOG.warn("got to stillvalid while not active");
return false;
}
if (i.getOffenders().size() != 1) return true;
if (predicate(i.getOffenders().firstElement(), dsgr)) {
// Now we know that this critic is still valid. What we need to
// figure out is if the corresponding to-do item is still valid.
// The to-do item is to be replaced if the name of some offender
// has changed that affects its description or if the contents
// of the list of offenders has changed.
// We check that by creating a new ToDoItem and then verifying
// that it looks exactly the same.
// This really creates a lot of to-do items that goes to waste.
ToDoItem item = toDoItem(i.getOffenders().firstElement(), dsgr);
return (item.equals(i));
}
return false;
}
/**
* @see org.argouml.cognitive.Poster#supports(org.argouml.cognitive.Decision)
*/
public boolean supports(Decision d) {
return supportedDecisions.contains(d);
}
/**
* @see org.argouml.cognitive.Poster#getSupportedDecisions()
*/
public Vector getSupportedDecisions() {
return supportedDecisions;
}
/**
* @param d the decision
*/
public void addSupportedDecision(Decision d) {
supportedDecisions.addElement(d);
}
/**
* @see org.argouml.cognitive.Poster#supports(org.argouml.cognitive.Goal)
*/
public boolean supports(Goal g) {
return supportedGoals.contains(g);
}
/**
* @see org.argouml.cognitive.Poster#getSupportedGoals()
*/
public Vector getSupportedGoals() {
return supportedGoals;
}
/**
* @param g the goal
*/
public void addSupportedGoal(Goal g) {
supportedGoals.addElement(g);
}
/**
* @see org.argouml.cognitive.Poster#containsKnowledgeType(java.lang.String)
*/
public boolean containsKnowledgeType(String type) {
return knowledgeTypes.contains(type);
}
/**
* @param type the knowledgetype
*/
public void addKnowledgeType(String type) {
knowledgeTypes.addElement(type);
}
/**
* @return the knowledgetypes
*/
public VectorSet getKnowledgeTypes() { return knowledgeTypes; }
/**
* @param kt the knowledgetypes
*/
public void setKnowledgeTypes(VectorSet kt) { knowledgeTypes = kt; }
/**
* Reset all knowledgetypes, and add the given one.
*
* @param t1 the only knowledgetype in string format
*/
public void setKnowledgeTypes(String t1) {
knowledgeTypes = new VectorSet();
addKnowledgeType(t1);
}
/**
* Reset all knowledgetypes, and add the given ones.
*
* @param t1 a knowledgetype in string format
* @param t2 a knowledgetype in string format
*/
public void setKnowledgeTypes(String t1, String t2) {
knowledgeTypes = new VectorSet();
addKnowledgeType(t1);
addKnowledgeType(t2);
}
/**
* Reset all knowledgetypes, and add the given ones.
*
* @param t1 a knowledgetype in string format
* @param t2 a knowledgetype in string format
* @param t3 a knowledgetype in string format
*/
public void setKnowledgeTypes(String t1, String t2, String t3) {
knowledgeTypes = new VectorSet();
addKnowledgeType(t1);
addKnowledgeType(t2);
addKnowledgeType(t3);
}
/**
* @param s the reason
* @return the code for the given reason
*/
public static int reasonCodeFor(String s) {
return 1 << (s.hashCode() % 62);
}
/**
* @return the trigger mask
*/
public long getTriggerMask() { return triggerMask; }
/**
* @param s the trigger to be added (is ORed into the mask)
*/
public void addTrigger(String s) {
int newCode = reasonCodeFor(s);
triggerMask |= newCode;
}
/**
* @param patternCode the mask to be checked
* @return true if it matches a trigger
*/
public boolean matchReason(long patternCode) {
return (triggerMask == 0) || ((triggerMask & patternCode) != 0);
}
/**
* @see org.argouml.cognitive.Poster#expand(java.lang.String,
* org.tigris.gef.util.VectorSet)
*/
public String expand(String desc, VectorSet offs) { return desc; }
/**
* @see org.argouml.cognitive.Poster#getClarifier()
*/
public Icon getClarifier() {
return clarifier;
}
////////////////////////////////////////////////////////////////
// criticism control
/** Reply true iff this Critic can execute. This fact is normally
* determined by a ControlMech.
*
* @return true iff this Critic can execute
*/
public boolean isActive() { return isActive; }
/** Make this critic active. From now on it can be applied to a
* design material in critiquing.
*/
public void beActive() {
if (!isActive) {
Configuration.setBoolean(getCriticKey(), true);
}
isActive = true;
}
/** Make this critic inactive. From now on it will be idle and will
* not be applied to a design material in critiquing.
*/
public void beInactive() {
if (isActive) {
Configuration.setBoolean(getCriticKey(), false);
}
isActive = false;
}
/** Add some attribute used by ControlMech to determine if this
* Critic should be active. Critics store control record so that
* stateful ControlMech's do not need to store a parallel data
* structure. But Critic's do not directy use or modify this
* data.
*
* @param name the key
* @param controlData the value
* @return the previous value of the specified key
* in this hashtable, or * * TODO: I would like a better default action, but goals * are typed and their values must be interperted by critics. They * are not as generic as the DecisionModel. * * @param dsgr the designer * @return true if relevant */ public boolean isRelevantToGoals(Designer dsgr) { return true; } //////////////////////////////////////////////////////////////// // corrective automations, wizards /** Create a new Wizard to help the user fix the identified problem. * This version assumes subclasses override getWizClass to return * the appropriate Class of wizard. Critic subclasses that need to * initialize their wizard might override this to call * super.makeWizard() and then work with the result. * * @param item the todo item * @return the wizard */ public Wizard makeWizard(ToDoItem item) { Class wizClass = getWizardClass(item); // if wizClass is not a subclass of Wizard, print a warning if (wizClass != null) { try { Wizard w = (Wizard) wizClass.newInstance(); w.setToDoItem(item); initWizard(w); return w; } catch (Exception ex) { LOG.error("Could not make wizard: " + item, ex); } } return null; } /** Return the Class of wizard that can fix the problem identifed by * this critic. * This method returns null, subclasses with wizards should override it. * * @param item the todo item * @return null if no wizard is defined. */ public Class getWizardClass(ToDoItem item) { return null; } /** Initialize a newly created wizard with information found by the * critic. This is called right after the wizard is made in * makeWizard() and after the wizard's ToDoItem is set. Any critic * that supports wizards should probably override this method, and * call super initWizard() first. * * @param w the wizard */ public void initWizard(Wizard w) { } //////////////////////////////////////////////////////////////// // accessors /** Reply a string used to determine if this critic would be * relevant to current design decisions. Strings returned from here * are compared to strings in the DecisionModel. * * @return the decision category */ public String getDecisionCategory() { return decisionCategory; } /** Set the decisionCategory, usually done in the constructor. I * have not yet thought of a case where dynamically changing the * Critic's decisionCategory is useful. * * @param c the category */ protected void setDecisionCategory(String c) { decisionCategory = c; } /** Reply a string used to contol critics according to * type. Examples include: correctness, completeness, consistency, * optimization, presentation, and alternative. * * @return the critic knowledge type */ public String getCriticType() { return criticType; } /** Reply the email address of the person who is the author or * maintainer of this critic. * * @see org.argouml.cognitive.Poster#getExpertEmail() */ public String getExpertEmail() { return emailAddr; } /** Set the email address of the person who is the author or * maintainer of this critic. * * @see org.argouml.cognitive.Poster#setExpertEmail(java.lang.String) */ public void setExpertEmail(String addr) { emailAddr = addr; } /** * Reply the headline used in feedback produced by this Critic. * * @param dm the design material * @param dsgr the designer * @return the headline */ public String getHeadline(Object dm, Designer dsgr) { return getHeadline(); } /** * Reply the headline used in feedback produced by this Critic. * * @param offenders the set of offenders * @param dsgr the designer * @return the headline */ public String getHeadline(VectorSet offenders, Designer dsgr) { return getHeadline(offenders.firstElement(), dsgr); } /** * Reply the headline used in feedback produced by this Critic. * * @return the headline */ public String getHeadline() { return headline; } /** * Set the headline used in feedback produced by this Critic. * * @param h the headline */ public void setHeadline(String h) { headline = h; } /** * Reply the priority used in feedback produced by this Critic. * * @param offenders the offenders * @param dsgr the designer * @return the priority */ public int getPriority(VectorSet offenders, Designer dsgr) { return priority; } /** * @param p the priority */ public void setPriority(int p) { priority = p; } /** * @return the priority */ public int getPriority() { return priority; } /** * Reply the description used in feedback produced by this Critic. * * @param offenders the offenders * @param dsgr the designer * @return the description */ public String getDescription(VectorSet offenders, Designer dsgr) { return description; } /** * @param d the description */ public void setDescription(String d) { description = d; } /** * @return the description */ public String getDescriptionTemplate() { return description; } /** * Reply the moreInfoURL used in feedback produced by this Critic. * * @param offenders the offenders * @param dsgr the designer * @return the more-info-url */ public String getMoreInfoURL(VectorSet offenders, Designer dsgr) { return moreInfoURL; } /** * @param m the more-info-url */ public void setMoreInfoURL(String m) { moreInfoURL = m; } /** * @return the more-info-url */ public String getMoreInfoURL() { return getMoreInfoURL(null, null); } /** * @param name the key * @param value the value */ protected void setArg(String name, Object value) { args.put(name, value); } /** * @param name the key * @return the value */ protected Object getArg(String name) { return args.get(name); } /** * @return the (key, value) pairs */ public Hashtable getArgs() { return args; } /** * @param h the new table of (key, value) pairs */ public void setArgs(Hashtable h) { args = h; } //////////////////////////////////////////////////////////////// // design feedback /** Reply the ToDoItem that the designer should see iff predicate() * returns true. By default it just fills in the fields of the * ToDoItem from accessor methods of this Critic. Critic Subclasses * may override this method or the accessor methods to add computed * fields to the ToDoItem. * * TODO: Critic's may want to add new fields to a * ToDoItem to make stillValid more efficent. * * @see Critic#critique */ public ToDoItem toDoItem(Object dm, Designer dsgr) { return new ToDoItem(this, dm, dsgr); } //////////////////////////////////////////////////////////////// // issue resolution /** TODO: Not implemented yet. The idea is that some * problems identified by Critic's can be fixed with certain design * manipulations (or transforms) that can be applied automatically * to resolve the problem. This method replies true iff the given * problem can be fixed. The fixIt() method actually does the fix. * * @see Critic#fixIt */ public boolean canFixIt(ToDoItem item) { return false; } /** TODO: Not implemented yet. If the given ToDoItem can * be fixed automatically, and the user wants that to happen, then do * it. Obviously, this depends on the specific Critic and * problem. By default this method does nothing. * * @see Critic#canFixIt */ public void fixIt(ToDoItem item, Object arg) { } /** * Reply a string that describes this Critic. Identical to getCriticName() * * @see java.lang.Object#toString() */ public String toString() { return getCriticName(); } } /* end class Critic */ |
... this post is sponsored by my books ... | |
![]() #1 New Release! |
![]() FP Best Seller |
Copyright 1998-2024 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.