001/**
002 * Copyright 2015 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.contentanalysis.video;
017
018import java.util.EnumSet;
019
020import org.apache.log4j.Logger;
021import org.quartz.JobExecutionContext;
022import org.quartz.JobExecutionException;
023
024import service.tut.pori.contentanalysis.AnalysisBackend;
025import service.tut.pori.contentanalysis.AnalysisBackend.Capability;
026import service.tut.pori.contentanalysis.BackendStatus;
027import service.tut.pori.contentanalysis.BackendStatusList;
028import core.tut.pori.context.ServiceInitializer;
029import core.tut.pori.users.UserIdentity;
030
031/**
032 * An implementation of ASyncTask, meant for executing a back-end feedback task.
033 * 
034 * Requires a valid taskId for execution, provided in a JobExecutionContext.
035 * 
036 */
037public class VideoBackendFeedbackTask extends VideoFeedbackTask {
038  @Override
039  public void execute(JobExecutionContext context) throws JobExecutionException {
040    executeAddTask(EnumSet.of(Capability.VIDEO_ANALYSIS, Capability.BACKEND_FEEDBACK), ServiceInitializer.getDAOHandler().getSQLDAO(VideoTaskDAO.class), getTaskId(context.getMergedJobDataMap()));
041  }
042  
043  /**
044   * A helper class building VideoTaskDetails usable with {@link VideoBackendFeedbackTask} and executable using {@link  service.tut.pori.contentanalysis.video.VideoContentCore#scheduleTask(VideoTaskDetails)}
045   * @see service.tut.pori.contentanalysis.video.VideoContentCore
046   * @see service.tut.pori.contentanalysis.video.VideoTaskDetails
047   */
048  public static class FeedbackTaskBuilder{
049    private static final Logger LOGGER = Logger.getLogger(FeedbackTaskBuilder.class);
050    private VideoTaskDetails _details = null;
051    
052    /**
053     * 
054     * @param taskType {@link service.tut.pori.contentanalysis.AsyncTask.TaskType#BACKEND_FEEDBACK}
055     * @throws IllegalArgumentException on unsupported/invalid task type
056     */
057    public FeedbackTaskBuilder(TaskType taskType) throws IllegalArgumentException {
058      if(taskType != TaskType.BACKEND_FEEDBACK){
059        throw new IllegalArgumentException("Invalid task type.");
060      }
061      _details = new VideoTaskDetails(taskType);
062    }
063    
064    /**
065     * Add video to feedback task if the given video has (valid) changes
066     * 
067     * @param video
068     * @return this
069     */
070    public FeedbackTaskBuilder addVideo(Video video){
071      if(video == null){
072        LOGGER.warn("Ignored null video.");
073      }else{
074        _details.addVideo(video);
075      }
076      return this;
077    }
078    
079    /**
080     * 
081     * @param videos
082     * @return this
083     */
084    public FeedbackTaskBuilder addVideos(VideoList videos){
085      if(VideoList.isEmpty(videos)){
086        LOGGER.warn("Ignored empty video list.");
087      }else{
088        for(Video p : videos.getVideos()){
089          addVideo(p);
090        }
091      }
092      return this;
093    }
094    
095    /**
096     * 
097     * @param userId
098     * @return this
099     */
100    public FeedbackTaskBuilder setUser(UserIdentity userId){
101      _details.setUserId(userId);
102      return this;
103    }
104    
105    /**
106     * 
107     * @param end
108     * @return this
109     * @throws IllegalArgumentException on null or invalid back-end
110     */
111    public FeedbackTaskBuilder addBackend(AnalysisBackend end) throws IllegalArgumentException{
112      if(end == null || !end.hasCapability(Capability.BACKEND_FEEDBACK)){
113        throw new IllegalArgumentException("The given back-end, id: "+end.getBackendId()+" does not have the required capability: "+Capability.BACKEND_FEEDBACK.name());
114      }
115      _details.setBackend(new BackendStatus(end, TaskStatus.NOT_STARTED));
116      return this;
117    }
118    
119    /**
120     * This will automatically filter out back-end with inadequate capabilities
121     * 
122     * @param backendStatusList
123     * @return this
124     */
125    public FeedbackTaskBuilder setBackends(BackendStatusList backendStatusList){
126      if(BackendStatusList.isEmpty(backendStatusList)){
127        LOGGER.debug("Empty backend status list.");
128        backendStatusList = null;
129      }else if((backendStatusList = BackendStatusList.getBackendStatusList(backendStatusList.getBackendStatuses(EnumSet.of(Capability.BACKEND_FEEDBACK)))) == null){ // filter out back-ends with invalid capabilities
130        LOGGER.warn("List contains no back-ends with valid capability "+Capability.BACKEND_FEEDBACK.name()+"for task type "+TaskType.BACKEND_FEEDBACK.name());
131      }
132      _details.setBackends(backendStatusList);
133      return this;
134    }
135    
136    /**
137     * 
138     * @return this
139     */
140    public FeedbackTaskBuilder clearVideos(){
141      _details.setVideoList(null);
142      return this;
143    }
144    
145    /**
146     * 
147     * @return video task details created from the given values
148     * @throws IllegalArgumentException on invalid value combination
149     */
150    public VideoTaskDetails build() throws IllegalArgumentException {
151      VideoList videoList = _details.getVideoList();
152      if(VideoList.isEmpty(videoList)){
153        throw new IllegalArgumentException("Back-end feedback must contain video list.");
154      }else if(!DeletedVideoList.isEmpty(_details.getDeletedVideoList())){
155        throw new IllegalArgumentException("Back-end feedback can only contain video list.");
156      }
157
158      return _details;
159    }
160  } // class FeedbackTaskBuilder
161}