001 package dk.deepthought.sidious.greenhouse;
002 
003 import java.util.Collection;
004 
005 import org.apache.commons.logging.Log;
006 import org.apache.commons.logging.LogFactory;
007 
008 import dk.deepthought.sidious.gui.SidiousOutput;
009 import dk.deepthought.sidious.planner.Plan;
010 import dk.deepthought.sidious.rules.Rule;
011 import dk.deepthought.sidious.services.ServiceEngine;
012 import dk.deepthought.sidious.supportsystem.Adjustable;
013 import dk.deepthought.sidious.supportsystem.PlanRequester;
014 import dk.deepthought.sidious.supportsystem.Repository;
015 import dk.deepthought.sidious.supportsystem.State;
016 import dk.deepthought.sidious.supportsystem.SuperLinkID;
017 import dk.deepthought.sidious.supportsystem.SystemSettings;
018 
019 /**
020  * This class represents a greenhouse and its properties.
021  
022  @author Deepthought
023  
024  */
025 public class Greenhouse implements PlanRequester, Runnable {
026 
027     private static final Log logger = LogFactory.getLog(Greenhouse.class);
028 
029     /**
030      * The id of this greenhouse.
031      */
032     private final SuperLinkID id;
033 
034     /**
035      * Boolean that holds interrupt status.
036      */
037     private volatile boolean interrupted = false;
038 
039     /**
040      * Collection of adjustables
041      */
042     private final Collection<Adjustable> adjustables;
043 
044     /**
045      * Collection of rules
046      */
047     private final Collection<Rule> rules;
048 
049     private boolean finished;
050 
051     private Plan currentPlan;
052 
053     /**
054      * Constructs a new instance of <code>Greenhouse</code> with the specified
055      * id, adjustables, and rules.
056      
057      @param id
058      *            the id of the greenhouse
059      @param adjustables
060      *            the adjustables associated with the greenhouse
061      @param rules
062      *            the rules associated with the greenhouse
063      */
064     public Greenhouse(final SuperLinkID id,
065             final Collection<Adjustable> adjustables,
066             final Collection<Rule> rules) {
067         if (id == null || adjustables == null || rules == null) {
068             throw new IllegalArgumentException("null is not a valid parameter");
069         }
070         if (adjustables.isEmpty() || rules.isEmpty()) {
071             throw new IllegalArgumentException(
072                     "An empty list is not a valid parameter");
073         }
074         this.id = id;
075         this.adjustables = adjustables;
076         this.rules = rules;
077     }
078 
079     /*
080      * (non-Javadoc)
081      
082      * @see dk.deepthought.sidious.supportsystem.PlanRequester#getAdjustables()
083      */
084     public Collection<Adjustable> getAdjustables() {
085         return adjustables;
086     }
087 
088     /*
089      * (non-Javadoc)
090      
091      * @see dk.deepthought.sidious.supportsystem.PlanRequester#getRules()
092      */
093     public Collection<Rule> getRules() {
094         return rules;
095     }
096 
097     /*
098      * (non-Javadoc)
099      
100      * @see dk.deepthought.sidious.supportsystem.PlanRequester#getState()
101      */
102     public State getState() {
103         if (logger.isDebugEnabled()) {
104             logger.debug("getState() - start");
105         }
106 
107         State returnState = ServiceEngine.getCurrentState();
108         if (logger.isDebugEnabled()) {
109             logger.debug("getState() - end - return value=" + returnState);
110         }
111         return returnState;
112     }
113 
114     /**
115      * Main loop of the Greenhouse. Controls the frequency of which a new plan
116      * is requested from the Blackboard.
117      
118      @see java.lang.Runnable#run()
119      */
120     public void run() {
121         if (logger.isDebugEnabled()) {
122             logger.debug("run() - start");
123         }
124         //FIXME Dette er bare ikke godt nok
125         //Fjern tråd run ting
126         while (!interrupted()) {
127             Repository.getBlackboard().requestPlan(this);
128             try {
129                 Thread.sleep(SystemSettings.getTimestep());
130             catch (InterruptedException e) {
131                 logger.error("Thread could not wait", e);
132             }
133         }
134 
135         if (logger.isDebugEnabled()) {
136             logger.debug("run() - end");
137         }
138     }
139 
140     /**
141      * Returns <code>true</code> if this thread has been interrupted,
142      <code>false</code> otherwise.
143      
144      @return <code>true</code> if interrupted
145      */
146     private boolean interrupted() {
147         return interrupted;
148     }
149 
150     /**
151      * Method interrupts the thread.
152      */
153     public void interrupt() {
154         if (logger.isDebugEnabled()) {
155             logger.debug("interrupt() - start")//$NON-NLS-1$
156         }
157 
158         interrupted = true;
159 
160         if (logger.isDebugEnabled()) {
161             logger.debug("interrupt() - end")//$NON-NLS-1$
162         }
163     }
164 
165     /*
166      * (non-Javadoc)
167      
168      * @see dk.deepthought.sidious.supportsystem.PlanRequester#getID()
169      */
170     public SuperLinkID getID() {
171         return id;
172     }
173 
174     /*
175      * (non-Javadoc)
176      
177      * @see dk.deepthought.sidious.supportsystem.PlanRequester#setPlan(dk.deepthought.sidious.planner.Plan)
178      */
179     public void setPlan(Plan plan) {
180         finished = true;
181         currentPlan = plan;
182         SidiousOutput.getInstance().addFinishedPlan(plan);
183     }
184     
185     /**
186      * Gets the current plan for this greenhouse.
187      @return the current plan of this
188      */
189     public Plan getCurrentPlan() {
190         return currentPlan;
191     }
192     
193     /**
194      @return <code>true</code> if a plan has been delivered
195      */
196     public boolean isFinished() {
197         return finished;
198     }
199 
200     /*
201      * (non-Javadoc)
202      
203      * @see java.lang.Object#toString()
204      */
205     @Override
206     public String toString() {
207         return getClass().getSimpleName() "[id=" + id + "]";
208     }
209 
210 }