001    package edu.nrao.sss.model.project.scheduling.priority;
002    
003    import java.util.Set;
004    import java.util.List;
005    import java.util.Map;
006    import java.util.HashMap;
007    
008    import edu.nrao.sss.model.project.scheduling.Schedulable;
009    
010    /**
011     * Returns a single measure for the priority of a <code>ScheduleBlock</code> or
012     * a set of scheduling priorities.
013     * @author slovelan
014     *
015     */
016    
017    public abstract class PriorityMeasure {
018            
019            private static final float INITIAL_WEIGHT = 1.0f;
020            protected PriorityMeasureType measureType = null;
021            protected Map<PriorityType,Float> priorityWeights = new HashMap<PriorityType,Float>();
022            
023            //---------------------------------------------------------
024            //                        Construction
025            //---------------------------------------------------------
026            
027            public PriorityMeasure( ){
028                    initialize( null );
029            }
030            
031            public PriorityMeasure( PriorityMeasure pm ){
032                    if ( pm == null ){
033                            throw new IllegalArgumentException( "Need to have a priority measure to copy!");
034                    }
035                    measureType = pm.getPriorityMeasureType();
036                    initialize( pm );
037            }
038            
039            private final void initialize( PriorityMeasure copy ){
040                    priorityWeights.clear();
041                    PriorityType[] pTypes = PriorityType.values();
042                    for ( PriorityType pt : pTypes ){
043                            float weight = INITIAL_WEIGHT;
044                            if ( copy != null ){
045                                    weight = copy.getWeight( pt );
046                            }
047                            priorityWeights.put( pt, weight );
048                    }
049            }
050            
051    
052            //---------------------------------------------------------
053            //                       Type
054            //---------------------------------------------------------
055            
056            /**
057             * Returns the method that is being used to summarize priorities.
058             * @return the method used to summarize priorities.
059             */
060            
061            public PriorityMeasureType getPriorityMeasureType(){
062                    return measureType;
063            }
064            
065            //-----------------------------------------------------------
066            //                    Weight
067            //-----------------------------------------------------------
068            
069            /**
070             * Sets the relative importance of a particular type of priority with regard to this
071             * priority measure.
072             * @param pt a particular type of priority.
073             * @param weight the importance this measure should attach to the priority type.
074             */
075    
076            public void setWeight( PriorityType pt, float weight ){
077                    if ( pt != null ){
078                            if ( weight >= 0 ){
079                                    priorityWeights.put( pt, weight );
080                            }
081                            else {
082                                    throw new IllegalArgumentException( "The weight must be nonnegative: "+weight );
083                            }
084                            
085                    }
086                    else {
087                            throw new IllegalArgumentException( "Please specify a priority type for the weight: "+weight );
088                    }
089            }
090            
091            /**
092             * Returns the relative importance of a particular type of priority with regard to
093             * this priority measure.
094             * @param pt a particular type of priority.
095             * @return the relative importance this measurement will attach to the priority type.
096             */
097            
098            public float getWeight( PriorityType pt ){
099                    if ( pt != null ){
100                            return priorityWeights.get( pt );
101                    }
102                    else {
103                            throw new IllegalArgumentException( "Please specify a priority type!");
104                    }
105            }
106            
107            //-----------------------------------------------------------------------
108            //                  Priority
109            //-----------------------------------------------------------------------
110            
111            
112            /**
113             * Returns a number summarizing the priority of the scheduling block.
114             * @param theBlock a scheduling block for which a priority is needed.
115             * @return a number summarizing the priority of the scheduling block.
116             */
117            
118            public abstract double getPriority( Schedulable theBlock );
119            
120            
121            /**
122             * Returns a number summarizing the priority of the set.
123             * @param thePriorities a set of {@code Priority} indicating an importance
124             *        with regard to a particular criteria.
125             * @return a number summarizing the priorities in the set.
126             */
127            
128            public abstract double getPriority( List<Priority> thePriorities );
129            
130            
131            //---------------------------------------------------------------------
132            //                        String Methods
133            //---------------------------------------------------------------------
134            
135            /**
136             * Returns a short description of this method of summarizing priorities.
137             * @return a short description of this method of summarizing priorities.
138             */
139            
140            public String getName(){
141                    String dName = "";
142                    if ( measureType != null ){
143                            dName = measureType.toString();
144                    }
145                    return dName;
146            }
147            
148            /**
149             * Returns a detailed description of this method of summarizing priorities.
150             * @return a detailed description of this method of summarizing priorities.
151             */
152            
153            public String toSummaryString(){
154                    StringBuilder sb = new StringBuilder();
155                    sb.append( "Name: "+getName() + "\n" );
156                    sb.append( "Priority Weights: " + "\n" );
157                    Set<PriorityType> keys = priorityWeights.keySet();
158                    for ( PriorityType pf : keys ){
159                            sb.append( " Priority: "+pf.toString()+" Weight: "+ priorityWeights.get( pf ) );
160                    }
161                    return sb.toString();
162            }
163            
164            public boolean equals( Object other ){
165                    boolean result = false;
166                    if ( other instanceof PriorityMeasure ){
167                            PriorityMeasure otherM = (PriorityMeasure) other;
168                            if ( measureType.equals( otherM.getPriorityMeasureType())){
169                                    PriorityType[] keys = PriorityType.values();
170                                    boolean equalWeights = true;
171                                    for ( PriorityType pt : keys ){
172                                            if ( getWeight( pt) != otherM.getWeight( pt )){
173                                                    equalWeights = false;
174                                                    break;
175                                            }
176                                    }
177                                    if ( equalWeights ){
178                                            result = true;
179                                    }
180                            }
181                    }
182                    return result;
183            }
184            
185            public int hashCode(){
186                    int result = 17;
187                    result = result * 11 + measureType.hashCode();
188                    PriorityType[] keys = PriorityType.values();
189                    for ( PriorityType pt : keys ){
190                            result = result * 11 + new Double( getWeight( pt )).hashCode();
191                    }
192                    return result;
193            }
194    }