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.util.HashMap;
027    
028    import se.liu.ida.critiquer.activities.Activity;
029    import se.liu.ida.critiquer.activities.ActivityUtils;
030    import se.liu.ida.critiquer.activities.parameters.TimeParameter;
031    
032    public class ConstraintFactory {
033    
034            private static HashMap<Class, Object> singletonConstraints = new HashMap<Class, Object>();
035    
036            public static VisualConstraint getVisualConstraint(Class visualConstraintClass) {
037                    Object obj = singletonConstraints.get(visualConstraintClass);
038                    if (obj instanceof VisualConstraint) {
039                            return (VisualConstraint) obj;
040                    } else {
041                            return null;
042                    }
043            }
044    
045            public static SingletonConstraint getSingletonConstraint(Class visualConstraintClass) {
046                    Object obj = singletonConstraints.get(visualConstraintClass);
047                    if (obj instanceof SingletonConstraint) {
048                            return (SingletonConstraint) obj;
049                    } else {
050                            return null;
051                    }
052            }
053    
054            public static TimeParameterOrdering createLaterThanConstraint(TimeParameter endtimeA1,
055                                                                                                                                      TimeParameter starttimeA2,
056                                                                                                                                      ConstraintPolicy policy) {
057                    TimeParameterOrdering paramOrder = new TimeParameterOrdering(endtimeA1, starttimeA2);
058                    paramOrder.setPolicy(policy);
059                    return paramOrder;
060            }
061    
062            /**
063         * 
064         * Visual constraints that are only supposed to be created once are created
065         * here. The ones that need to be updated when parameter values change
066         * should inherit from <code>StandardConstraint</code> so that they are
067         * added to the list of activity update listeners through the default
068         * constructor of that class.
069         * 
070         * @param constraintClass
071         * @param enabled
072         */
073            public static void createSingletonVisualConstraint(Class constraintClass, boolean enabled) {
074    
075                    if (VisualConstraint.class.isAssignableFrom(constraintClass) && SingletonConstraint.class.isAssignableFrom(constraintClass)) {
076                            if (!singletonConstraints.containsKey(constraintClass)) {
077                                    try {
078    
079                                            VisualConstraint visualConstraint = (VisualConstraint) constraintClass.newInstance();
080                                            singletonConstraints.put(constraintClass, visualConstraint);
081                                            VisualConstraints.addConstraint((VisualConstraint) visualConstraint);
082                                            VisualConstraints.setConstraintEnabled(constraintClass, enabled);
083    
084                                    } catch (Exception e) {
085                                            e.printStackTrace();
086                                    }
087                            } else {
088                                    System.out.println("Note: Trying to create already existing singleton constraint of type " + constraintClass.getSimpleName());
089                            }
090                    } else {
091                            System.err.println("Wrong type of argument to enableConstraint: " + constraintClass);
092                    }
093    
094            }
095    
096            /**
097         * 
098         * Used when creating a sub-activity that is supposed to be performed within
099         * the time frame of the parent activity. This constraint makes sure the
100         * child activity cannot start before the parent activity.
101         * 
102         * @param a1
103         *            the parent activity
104         * @param a2
105         *            the child activity
106         * @return a time parameter ordering constraint
107         */
108            public static TimeParameterOrdering connectStartToStart(Activity a1, Activity a2) {
109                    TimeParameter a1StartTime = ActivityUtils.getStartTimeParameter(a1);
110                    TimeParameter a2StartTime = ActivityUtils.getStartTimeParameter(a2);
111                    TimeParameterOrdering missionStartConstraint = ConstraintFactory.createLaterThanConstraint(a1StartTime,
112                                    a2StartTime,
113                                    ConstraintPolicy.MODIFY_VALUES);
114    
115                    return missionStartConstraint;
116            }
117    
118            /**
119         * 
120         * Used when creating a sub-activity that is supposed to be performed within
121         * the time frame of the parent activity. This constraint ensures taht the
122         * child activity cannot end after the parent activity.
123         * 
124         * @param parent
125         *            the parent activity
126         * @param child
127         *            the child activity
128         * @return a time parameter ordering constraint
129         */
130            public static TimeParameterOrdering connectEndToEnd(Activity parent, Activity child) {
131                    TimeParameter parentEndTime = ActivityUtils.getEndTimeParameter(parent);
132                    TimeParameter childEndTime = ActivityUtils.getEndTimeParameter(child);
133                    TimeParameterOrdering missionEndConstraint = ConstraintFactory.createLaterThanConstraint(childEndTime,
134                                    parentEndTime,
135                                    ConstraintPolicy.MODIFY_VALUES);
136    
137                    return missionEndConstraint;
138            }
139    
140            /**
141         * Make sure the activity is internally consistent so that start always
142         * comes before end
143         * 
144         * @param a
145         * @return a parameter order constraint
146         * 
147         */
148            public static TimeParameterOrdering connectStartToEnd(Activity a) {
149                    TimeParameter start = ActivityUtils.getStartTimeParameter(a);
150                    TimeParameter end = ActivityUtils.getEndTimeParameter(a);
151                    TimeParameterOrdering internalTimeConstraint = ConstraintFactory.createLaterThanConstraint(start,
152                                    end,
153                                    ConstraintPolicy.MODIFY_VALUES);
154    
155                    return internalTimeConstraint;
156            }
157    
158            /**
159         * Connect two activities to form a sequence.
160         * 
161         * @param a1
162         *            the activity that should be performed first
163         * @param a2
164         *            the activity that should come second
165         * @return an ordering constraint that assures that activity a1 comes before a2
166         */
167            public static TimeParameterOrdering connectEndToStart(Activity a1, Activity a2) {
168    
169                    TimeParameter endtimeA1 = ActivityUtils.getEndTimeParameter(a1);
170                    TimeParameter starttimeA2 = ActivityUtils.getStartTimeParameter(a2);
171                    TimeParameterOrdering paramOrder = ConstraintFactory.createLaterThanConstraint(endtimeA1,
172                                    starttimeA2,
173                                    ConstraintPolicy.MODIFY_VALUES);
174                    
175                    return paramOrder;
176            }
177    
178    }