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}