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.Color;
027    import java.util.ArrayList;
028    import java.util.HashSet;
029    import java.util.List;
030    
031    import se.liu.ida.critiquer.activities.AbstractParamChangedListener;
032    import se.liu.ida.critiquer.activities.Activity;
033    import se.liu.ida.critiquer.gui.AbstractView;
034    import se.liu.ida.critiquer.gui.View;
035    
036    /**
037     * <p>
038     * Abstract class for those constraints only interested in when parameter values
039     * are changed. Provide dummy implementations for all other methods. To use
040     * these constraints, we must make sure they are listed in the
041     * ReferenceHolder.constraintClasses list. These constraints, if created by the
042     * ConstraintFactory, use the default constructor in this class that adds them
043     * as ActivityUpdateListeners so they do <i>NOT</i> have to register themselves
044     * as activity update listeners.
045     * </p>
046     * 
047     * <p>
048     * This class also provides a dummy implementation of
049     * <code>evaluateActivities</code> since we would rather like to have
050     * constraints update themselves when parameter values change and not do it
051     * manually on request.
052     * </p>
053     */
054    public abstract class StandardConstraint extends AbstractParamChangedListener implements
055                                                                                                                                                             SingletonConstraint,
056                                                                                                                                                             VisualConstraint {
057    
058            private boolean                                                 active            = false;
059            /**
060             * Used to information other parties that this constraint is violated
061             */
062            private boolean consistent = true;
063            private Color                                                     color            = Color.RED;
064    
065            protected ArrayList<Class<? extends View>> applicableViews = new ArrayList<Class<? extends View>>();
066            protected static HashSet<ConstraintStatusListener> statusListeners = new HashSet<ConstraintStatusListener>();
067            
068            @SuppressWarnings("unchecked")
069            public boolean isApplicableFor(View view) {
070                    boolean applicable = false;
071                    for (Class c : getApplicableViews()) {
072                            if (c.isAssignableFrom(view.getClass())) {
073                                    applicable = true;
074                                    break;
075                            }
076                    }
077                    return applicable;
078            }
079    
080            protected StandardConstraint() {
081                    Activity.addActivityUpdateListener(this);
082            }
083    
084            public Color getColor() {
085                    return color;
086            }
087    
088            public void setColor(Color c) {
089                    color = c;
090            }
091    
092            /**
093         * By default, all constraints should be visible in all views
094         */
095            public List<Class<? extends View>> getApplicableViews() {
096                    if (applicableViews.isEmpty()) {
097                            initApplicableViews();
098                    }
099                    return applicableViews;
100            }
101    
102            protected void initApplicableViews() {
103                    applicableViews.add(AbstractView.class);
104            }
105    
106            /**
107         * @see se.liu.ida.critiquer.constraints.VisualConstraint#isActive()
108         */
109            public boolean isActive() {
110                    return active;
111            }
112    
113            /**
114             * 
115             * Set active status and notify status listeners
116         * @see se.liu.ida.critiquer.constraints.VisualConstraint#setActive(boolean)
117         */
118            public void setActive(boolean active) {
119                    this.active = active;
120                    for (ConstraintStatusListener listener : statusListeners) {
121                            listener.activeStatusChanged(this);
122                    }
123            }
124    
125            /**
126             * 
127             * Add to the list of update listeners
128             * 
129             * @see se.liu.ida.critiquer.constraints.VisualConstraint#addStatusListener(se.liu.ida.critiquer.constraints.ConstraintStatusListener)
130             */
131            public static void addStatusListener(ConstraintStatusListener l) {
132                    statusListeners.add(l);
133            }
134    
135            /** 
136             * 
137             * Remove from the list of update listeners
138             * @see se.liu.ida.critiquer.constraints.VisualConstraint#removeStatusListener(se.liu.ida.critiquer.constraints.ConstraintStatusListener)
139             */
140            public static void removeStatusListener(ConstraintStatusListener l) {
141                    statusListeners.remove(l);
142            }
143    
144            /**
145             * @return Returns the consistent.
146             */
147            public boolean isConsistent() {
148                    return consistent;
149            }
150    
151            /**
152             * Update violation status and notify status listeners
153             * @param consistent The consistent to set.
154             */
155            protected void setConsistent(boolean consistent) {
156                    this.consistent = consistent;
157                    for (ConstraintStatusListener listener : statusListeners) {
158                            listener.violationStatusChanged(this);
159                    }
160            }
161    
162    }