001    package edu.nrao.sss.model.project;
002    
003    import java.util.ArrayList;
004    import java.util.Arrays;
005    import java.util.Collection;
006    import java.util.EnumSet;
007    
008    //import org.apache.log4j.Logger;
009    
010    import edu.nrao.sss.model.resource.TelescopeConfiguration;
011    import edu.nrao.sss.util.EventSetStatus;
012    import edu.nrao.sss.util.Filter;
013    
014    /**
015     * A filter that operates on {@link ProgramBlock program blocks}.
016     * <p>
017     * <b>Version Info:</b>
018     * <table style="margin-left:2em">
019     *   <tr><td>$Revision: 1709 $</td></tr>
020     *   <tr><td>$Date: 2008-11-14 11:22:37 -0700 (Fri, 14 Nov 2008) $</td></tr>
021     *   <tr><td>$Author: dharland $ (last person to modify)</td></tr>
022     * </table></p>
023     * 
024     * @author David M. Harland
025     * @since 2008-06-11
026     */
027    public class ProgramBlockFilter
028      implements Filter<ProgramBlock>
029    {
030    //private static final Logger log = Logger.getLogger(ProgramBlockFilter.class);
031    
032      private EnumSet<EventSetStatus>         execStatuses;
033      private EnumSet<TelescopeConfiguration> teleCfgs;
034      
035      //TODO create individual criteria variables
036    
037      /**
038       * Creates a new wide-open filter that allows all program blocks to pass.
039       */
040      public ProgramBlockFilter()
041      {
042        execStatuses = EnumSet.noneOf(EventSetStatus.class);
043        teleCfgs     = EnumSet.noneOf(TelescopeConfiguration.class);
044        
045        clearAll();
046      }
047    
048      //============================================================================
049      // CLEARING THE FILTERING CRITERIA
050      //============================================================================
051    
052      /**
053       * Sets this filter to a wide-open state.
054       */
055      public void clearAll()
056      {
057        clearExecStatuses();
058        //TODO clear individual criteria
059      }
060    
061      /**
062       * Sets the execution status criterion into its wide-open state.
063       * This means that no program block will be blocked by this filter due
064       * to its event status.
065       */
066      public void clearExecStatuses()
067      {
068        execStatuses.addAll(Arrays.asList(EventSetStatus.values())); 
069      }
070      
071      /**
072       * Sets the telescope configuration criterion into its wide-open state.
073       * This means that no program block will be blocked by this filter due
074       * to its preferred configuration(s).
075       */
076      public void clearTelescopeConfigurations()
077      {
078        teleCfgs.addAll(Arrays.asList(TelescopeConfiguration.values()));
079      }
080      
081      //TODO clear-methods for individual criteria
082    
083      //============================================================================
084      // SETTING THE FILTER CRITERIA
085      //============================================================================
086    
087      /**
088       * Sets the execution status criterion.
089       * Only those program blocks that have a status equal to one of those
090       * in the parameter list may pass through this filter.
091       * 
092       * @param goodStatuses
093       *   a list of execution statuses.  Any program block passing through
094       *   this filter must have one of these statuses.
095       *   
096       * @see #clearExecStatuses()
097       */
098      public void setExecStatuses(EventSetStatus... goodStatuses)
099      {
100        execStatuses.clear();
101        
102        for (EventSetStatus ess : goodStatuses)
103          execStatuses.add(ess);
104      }
105      
106      /**
107       * Sets the telescope configuration criterion.
108       * Only those program blocks that have a preferred configuration equal
109       * to one of those in the parameter list may pass through this filter.
110       * 
111       * @param goodCfgs
112       *   a list of telescope configuations .  Any program block passing through
113       *   this filter must have one or more of its preferred configurations
114       *   in this list.
115       */
116      public void setTelescopeConfigurations(TelescopeConfiguration... goodCfgs)
117      {
118        teleCfgs.clear();
119        
120        for (TelescopeConfiguration tc : goodCfgs)
121          teleCfgs.add(tc);
122      }
123      
124      //TODO set-methods for individual criteria
125      //  Some possibilities: pref LST start, status, is-ready-for-scheduling,
126      //                      total duration, sched type
127      
128      //============================================================================
129      // APPLYING THIS FILTER
130      //============================================================================
131    
132      public boolean blocks(ProgramBlock pb)
133      {
134        //Filter blocks all null SBs
135        if (pb == null)
136          return true;
137        
138        //Event status
139        if (!execStatuses.contains(pb.getExecutionStatus()))
140          return true;
141        
142        //Telescope configuration
143        boolean blockPb = true;
144        for (TelescopeConfiguration pbCfg : pb.getAcceptableConfigurations())
145        {
146          if (teleCfgs.contains(pbCfg))
147          {
148            blockPb = false;
149            break;
150          }
151        }
152        if (blockPb)
153          return true;
154        
155        //TODO use individual criteria
156    
157        return false;
158      }
159    
160      public boolean allows(ProgramBlock pb)
161      {
162        return !blocks(pb);
163      }
164      
165      /**
166       * Selects those objects in {@code bag} that are program blocks and that
167       * can pass through this filter.  The selections are added to a new collection
168       * and returned.  If the bag holds no such objects, the returned collection
169       * will be empty.
170       * <p>
171       * The original collection ({@code bag}) is not altered.</p>
172       * 
173       * @param bag
174       *   a collection of objects.
175       * 
176       * @return
177       *   a collection of program blocks from {@code bag} that were able to
178       *   pass through this filter.
179       */
180      public Collection<ProgramBlock> selectFrom(Collection<?> bag)
181      {
182        Collection<ProgramBlock> selection = new ArrayList<ProgramBlock>();
183        
184        for (Object candidate : bag)
185        {
186          if (candidate instanceof ProgramBlock)
187          {
188            ProgramBlock pb = (ProgramBlock)candidate;
189            
190            if (this.allows(pb))
191              selection.add(pb);
192          }
193        }
194        
195        return selection;
196      }
197    }