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;
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.Capability;
025import core.tut.pori.context.ServiceInitializer;
026import core.tut.pori.users.UserIdentity;
027
028/**
029 * An implementation of ASyncTask, meant for executing a back-end feedback task.
030 * 
031 * Requires a valid taskId for execution, provided in a JobExecutionContext.
032 * 
033 */
034public class PhotoBackendFeedbackTask extends PhotoFeedbackTask {
035
036  @Override
037  public void execute(JobExecutionContext context) throws JobExecutionException {
038    executeAddTask(EnumSet.of(Capability.PHOTO_ANALYSIS, Capability.BACKEND_FEEDBACK), ServiceInitializer.getDAOHandler().getSQLDAO(PhotoTaskDAO.class), getTaskId(context.getMergedJobDataMap()));
039  }
040
041  /**
042   * A helper class building PhotoTaskDetails usable with {@link PhotoBackendFeedbackTask} and executable using {@link service.tut.pori.contentanalysis.CAContentCore#scheduleTask(PhotoTaskDetails)}}
043   * @see service.tut.pori.contentanalysis.CAContentCore
044   * @see service.tut.pori.contentanalysis.PhotoTaskDetails
045   */
046  public static class FeedbackTaskBuilder{
047    private static final Logger LOGGER = Logger.getLogger(FeedbackTaskBuilder.class);
048    private PhotoTaskDetails _details = null;
049    
050    /**
051     * 
052     * @param taskType {@link service.tut.pori.contentanalysis.AsyncTask.TaskType#BACKEND_FEEDBACK}
053     * @throws IllegalArgumentException on unsupported/invalid task type
054     */
055    public FeedbackTaskBuilder(TaskType taskType) throws IllegalArgumentException {
056      super();
057      if(taskType != TaskType.BACKEND_FEEDBACK){
058        throw new IllegalArgumentException("Invalid task type.");
059      }
060      _details = new PhotoTaskDetails(taskType);
061    }
062    
063    /**
064     * Add photo to feedback task if the given photo has (valid) changes
065     * 
066     * @param photo
067     * @return this
068     */
069    public FeedbackTaskBuilder addPhoto(Photo photo){
070      if(photo == null){
071        LOGGER.warn("Ignored null photo.");
072      }else{
073        _details.addPhoto(photo);
074      }
075      return this;
076    }
077    
078    /**
079     * 
080     * @param photos
081     * @return this
082     */
083    public FeedbackTaskBuilder addPhotos(PhotoList photos){
084      if(PhotoList.isEmpty(photos)){
085        LOGGER.warn("Ignored empty photo list.");
086      }else{
087        for(Photo p : photos.getPhotos()){
088          addPhoto(p);
089        }
090      }
091      return this;
092    }
093    
094    /**
095     * 
096     * @param userId
097     * @return this
098     */
099    public FeedbackTaskBuilder setUser(UserIdentity userId){
100      _details.setUserId(userId);
101      return this;
102    }
103    
104    /**
105     * 
106     * @param confidence
107     * @return this
108     */
109    public FeedbackTaskBuilder setUserConfidence(Double confidence){
110      _details.setUserConfidence(confidence);
111      return this;
112    }
113    
114    /**
115     * 
116     * @param end
117     * @return this
118     * @throws IllegalArgumentException on null or invalid back-end
119     */
120    public FeedbackTaskBuilder addBackend(AnalysisBackend end) throws IllegalArgumentException{
121      if(end == null || !end.hasCapability(Capability.BACKEND_FEEDBACK)){
122        throw new IllegalArgumentException("The given back-end, id: "+end.getBackendId()+" does not have the required capabilities: "+Capability.USER_FEEDBACK.name());
123      }
124      _details.setBackend(new BackendStatus(end, TaskStatus.NOT_STARTED));
125      return this;
126    }
127    
128    /**
129     * This will automatically filter out back-end with inadequate capabilities
130     * 
131     * @param backendStatusList
132     * @return this
133     */
134    public FeedbackTaskBuilder setBackends(BackendStatusList backendStatusList){
135      if(BackendStatusList.isEmpty(backendStatusList)){
136        LOGGER.warn("Empty backend status list.");
137        backendStatusList = null;
138      }else if((backendStatusList = BackendStatusList.getBackendStatusList(backendStatusList.getBackendStatuses(EnumSet.of(Capability.BACKEND_FEEDBACK)))) == null){ // filter out back-ends with invalid capabilities
139        LOGGER.warn("List contains no back-ends with valid capability "+Capability.BACKEND_FEEDBACK.name()+"for task type "+TaskType.BACKEND_FEEDBACK.name());
140      }
141      _details.setBackends(backendStatusList);
142      return this;
143    }
144    
145    /**
146     * 
147     * @return this
148     */
149    public FeedbackTaskBuilder clearPhotos(){
150      _details.setPhotoList(null);
151      return this;
152    }
153    
154    /**
155     * 
156     * @return new task details based on the given data or null if no data was given
157     * @throws IllegalArgumentException 
158     */
159    public PhotoTaskDetails build() throws IllegalArgumentException {
160      PhotoList photoList = _details.getPhotoList();
161      if(PhotoList.isEmpty(photoList)){
162        throw new IllegalArgumentException("Back-end feedback must contain photo list.");
163      }else if(!PhotoList.isEmpty(_details.getReferencePhotoList()) || !PhotoList.isEmpty(_details.getSimilarPhotoList()) || !PhotoList.isEmpty(_details.getDeletedPhotoList()) || !PhotoList.isEmpty(_details.getDissimilarPhotoList())){
164        throw new IllegalArgumentException("Back-end feedback can only contain photo list.");
165      }
166
167      return _details;
168    }
169  } // class FeedbackTaskBuilder
170}