001    /**
002     * planningtool - A Planning Tool with Critiquing Support.
003     * 
004     * Copyright (C) 2006 olale
005    
006     * This program is free software; you can redistribute it and/or
007     * modify it under the terms of the GNU General Public License
008     * as published by the Free Software Foundation; either version 2
009     * of the License, or (at your option) any later version.
010    
011     * This program is distributed in the hope that it will be useful,
012     * but WITHOUT ANY WARRANTY; without even the implied warranty of
013     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
014     * GNU General Public License for more details.
015    
016     * You should have received a copy of the GNU General Public License
017     * along with this program; if not, write to the Free Software
018     * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
019    
020     * Contact information: 
021     * E-mail: olale@ida.liu.se
022     *         olale@lysator.liu.se
023     */
024    package se.liu.ida.critiquer.constraints;
025    
026    import java.awt.Graphics2D;
027    import java.util.HashMap;
028    
029    import se.liu.ida.critiquer.activities.Activity;
030    import se.liu.ida.critiquer.activities.ActivityUtils;
031    import se.liu.ida.critiquer.activities.ToplevelActivity;
032    import se.liu.ida.critiquer.activities.parameters.Parameter;
033    import se.liu.ida.critiquer.gui.TaskView;
034    import se.liu.ida.critiquer.gui.View;
035    
036    /**
037     * 
038     * If an activity needs to have some special properties in order to be
039     * considered completely specified, we can use this constraint to notify the
040     * user. For instance, we may require that there should be a top-level activity
041     * for each mission and therefore, all new activities except top-level
042     * activities should have a parent.
043     * 
044     * @author olale
045     * 
046     */
047    public class IncompleteActivity extends StandardConstraint implements TextCritic {
048    
049            /**
050         * 
051         */
052            private static final long serialVersionUID = 1L;
053    
054            private HashMap<Activity,String> incompleteActivities = new HashMap<Activity,String>();
055            /**
056         * 
057         */
058            public IncompleteActivity() {
059                    super();
060            }
061    
062            
063            
064            /**
065             * @see se.liu.ida.critiquer.activities.AbstractParamChangedListener#activityCreated(se.liu.ida.critiquer.activities.Activity)
066             */
067            @Override
068            public void activityCreated(Activity activity) {
069                    if (!isConsistent(activity)) {
070                            critic(activity);
071                    }
072            }
073    
074    
075    
076            private void critic(Activity activity) {
077                    incompleteActivities.put(activity,"* "+activity+" should have a parent activity\n");
078                    setConsistent(false);   
079            }
080    
081    
082    
083            public String getText() {
084                    String s = "";
085                    for (String text : incompleteActivities.values()) {
086                            s += text;
087                    }
088                    return s;
089            }
090    
091    
092    
093            private boolean isConsistent(Activity activity) {
094                    return activity.hasParent() || (activity instanceof ToplevelActivity);
095            }
096    
097            /* (non-Javadoc)
098             * @see se.liu.ida.critiquer.activities.AbstractParamChangedListener#activityUpdated(se.liu.ida.critiquer.activities.Activity)
099             */
100            @Override
101            public void activityUpdated(Activity a) {
102                    if (isConsistent(a)) {
103                            removeCritique(a);
104                    } else {
105                            critic(a);
106                    }
107                            
108            }
109    
110    
111    
112            private void removeCritique(Activity a) {
113                    incompleteActivities.remove(a);
114                    setConsistent(incompleteActivities.isEmpty());
115            }
116    
117            /**
118         * 
119         * The names of the activity may change so update the text
120         * 
121         * @see se.liu.ida.critiquer.activities.AbstractParamChangedListener#paramChanged(se.liu.ida.critiquer.activities.Activity,
122         *      se.liu.ida.critiquer.activities.parameters.Parameter)
123         */
124            @Override
125            public <T> void paramChanged(Activity activity, Parameter<T> p) {
126                    if (p==ActivityUtils.getNameParameter(activity)) {
127                            activityUpdated(activity);
128                    }
129            }
130    
131            /*
132         * (non-Javadoc)
133         * 
134         * @see se.liu.ida.critiquer.constraints.SingletonConstraint#getDescription()
135         */
136            public String getDescription() {
137                    // TODO Auto-generated method stub
138                    return "Checks whether or not activities are completely specified";
139            }
140    
141            /*
142         * (non-Javadoc)
143         * 
144         * @see se.liu.ida.critiquer.gui.ViewRenderingListener#viewUpdated(se.liu.ida.critiquer.gui.View,
145         *      java.awt.Graphics2D)
146         */
147            public void viewUpdated(View v, Graphics2D g2) {
148                    // TODO Auto-generated method stub
149    
150            }
151    
152    
153    
154            /**
155             * Set this critic visible in the graph view only
156             * 
157             * @see se.liu.ida.critiquer.constraints.StandardConstraint#initApplicableViews()
158             */
159            @Override
160            protected void initApplicableViews() {
161                    applicableViews.add(TaskView.class);
162            }
163    
164            
165            
166    }