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}