001/**
002 * Copyright 2016 Tampere University of Technology, Pori Department
003 * 
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 * 
008 *   http://www.apache.org/licenses/LICENSE-2.0
009 * 
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package service.tut.pori.apilta.sensors.datatypes;
017
018import java.util.List;
019import java.util.Set;
020
021import javax.xml.bind.annotation.XmlAccessType;
022import javax.xml.bind.annotation.XmlAccessorType;
023import javax.xml.bind.annotation.XmlElementRef;
024import javax.xml.bind.annotation.XmlElementWrapper;
025import javax.xml.bind.annotation.XmlRootElement;
026
027import org.apache.log4j.Logger;
028import org.quartz.JobBuilder;
029
030import service.tut.pori.apilta.sensors.SensorTaskDAO;
031import service.tut.pori.tasks.BackendTaskJob;
032import service.tut.pori.tasks.datatypes.Task;
033import service.tut.pori.tasks.datatypes.TaskBackend;
034import core.tut.pori.context.ServiceInitializer;
035
036/**
037 * Represents a single sensor task
038 * 
039 */
040@XmlRootElement(name=service.tut.pori.tasks.Definitions.ELEMENT_TASK)
041@XmlAccessorType(XmlAccessType.NONE)
042public class SensorTask extends Task{
043  private static final Logger LOGGER = Logger.getLogger(SensorTask.class);
044  @XmlElementWrapper(name = Definitions.ELEMENT_WHEN)
045  @XmlElementRef(type = Condition.class)
046  private List<Condition> _conditions = null;
047  @XmlElementWrapper(name = Definitions.ELEMENT_WHAT)
048  @XmlElementRef(type = Output.class)
049  private List<Output> _output = null;
050  /** Optional element for containing the task results */
051  @XmlElementRef(type = MeasurementList.class)
052  private MeasurementList _data = null;
053
054  @Override
055  public String getCallbackUri() {
056    return ServiceInitializer.getPropertyHandler().getRESTBindContext()+service.tut.pori.apilta.sensors.Definitions.SERVICE_SENSORS+"/"+service.tut.pori.tasks.Definitions.METHOD_TASK_FINISHED;
057  }
058
059  @Override
060  public SensorTaskDAO getTaskDao() {
061    return ServiceInitializer.getDAOHandler().getDAO(SensorTaskDAO.class);
062  }
063
064  /**
065   * 
066   * @return list of {@link Condition}s
067   */
068  public List<Condition> getConditions() {
069    return _conditions;
070  }
071
072  /**
073   * 
074   * @param conditions
075   */
076  public void setConditions(List<Condition> conditions) {
077    _conditions = conditions;
078  }
079
080  /**
081   * @return the output
082   */
083  public List<Output> getOutput() {
084    return _output;
085  }
086
087  /**
088   * @param output the output to set
089   */
090  public void setOutput(List<Output> output) {
091    _output = output;
092  }
093
094  /**
095   * @return the data
096   */
097  public MeasurementList getMeasurements() {
098    return _data;
099  }
100
101  /**
102   * @param data the data to set
103   */
104  public void setMeasurements(MeasurementList data) {
105    _data = data;
106  }
107  
108  /**
109   * 
110   */
111  public SensorTask() {
112    super();
113  }
114  
115  /**
116   * Create new sensor task based on the details of the base class task
117   * 
118   * @param task
119   */
120  public SensorTask(Task task) {
121    super(task);
122  }
123
124  /**
125   * @return true if the task is valid, a valid task must have valid output+condition lists OR a valid measurement list (NOT both)
126   */
127  @Override
128  protected boolean isValid() {
129    if(!super.isValid()){
130      LOGGER.debug("Invalid base task.");
131      return false;
132    }else if(MeasurementList.isValid(_data)){
133      if(_conditions != null || _output != null){
134        LOGGER.debug("Giving measurement list in combination with output or condition list is not allowed.");
135        return false;
136      }
137      
138      List<TaskBackend> backends = getBackends();
139      for(Measurement measurement : _data.getMeasurements()){ // check that the measurements do not contain back end identifiers that are not present in the task back end list
140        Long backendId = measurement.getBackendId();
141        boolean found = false;
142        for(TaskBackend backend : backends){
143          if(backend.getBackendId().equals(backendId)){
144            found = true;
145            break;
146          }
147        } // for back end
148        if(!found){
149          LOGGER.debug("Back end, id: "+backendId+" is not present in the task back end list.");
150          return false;
151        }
152      } // for measurement
153    }else{
154      if(_conditions == null || _output == null || _conditions.isEmpty() || _output.isEmpty()){
155        LOGGER.debug("No conditions, output and back ends.");
156        return false;
157      }
158      
159      for(Condition condition : _conditions){
160        if(!Condition.isValid(condition)){
161          LOGGER.debug("Invalid condition.");
162          return false;
163        }
164      }
165      
166      for(Output o : _output) {
167        if(!Output.isValid(o)){
168          LOGGER.debug("Invalid output.");
169          return false;
170        }
171      }
172    }
173    
174    return true;
175  }
176
177  @Override
178  public JobBuilder getBuilder() {
179    Set<String> taskTypes = getTaskTypes();
180    if(taskTypes == null){
181      LOGGER.warn("No task types defined, returning builder for "+BackendTaskJob.class.toString());
182      return BackendTaskJob.getBuilder(this);
183    }else if(taskTypes.contains(service.tut.pori.tasks.Definitions.TASK_TYPE_VIRTUAL)){
184      LOGGER.debug("Virtual task, returning builder for "+VirtualSensorTaskJob.class.toString());
185      return VirtualSensorTaskJob.getBuilder(this);
186    }else{
187      LOGGER.debug("Not a virtual task, returning builder for "+BackendTaskJob.class.toString());
188      return BackendTaskJob.getBuilder(this);
189    }
190  }
191}