001/** 002 * Copyright 2014 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 018 019import java.util.HashMap; 020import java.util.Map; 021 022import javax.xml.bind.annotation.XmlAccessType; 023import javax.xml.bind.annotation.XmlAccessorType; 024import javax.xml.bind.annotation.XmlElement; 025import javax.xml.bind.annotation.XmlRootElement; 026 027import org.apache.commons.lang3.StringUtils; 028 029import core.tut.pori.context.ServiceInitializer; 030import service.tut.pori.contentanalysis.AsyncTask.TaskType; 031 032/** 033 * An implementation of AbstractTaskDetails, which can be used to define a photo analysis task, or a feedback task. 034 * 035 * <h2>Conditional Elements</h2> 036 * <ul> 037 * <li>{@value service.tut.pori.contentanalysis.Definitions#ELEMENT_DELETED_PHOTOLIST}</li> 038 * <li>{@value service.tut.pori.contentanalysis.Definitions#ELEMENT_DISSIMILAR_PHOTOLIST}</li> 039 * <li>{@value service.tut.pori.contentanalysis.Definitions#ELEMENT_PHOTOLIST}</li> 040 * <li>{@value service.tut.pori.contentanalysis.Definitions#ELEMENT_REFERENCE_PHOTOLIST}</li> 041 * <li>{@value service.tut.pori.contentanalysis.Definitions#ELEMENT_SIMILAR_PHOTOLIST}</li> 042 * </ul> 043 * 044 * 045 * One of {@value service.tut.pori.contentanalysis.Definitions#ELEMENT_PHOTOLIST}, {@value service.tut.pori.contentanalysis.Definitions#ELEMENT_REFERENCE_PHOTOLIST} or {@value service.tut.pori.contentanalysis.Definitions#ELEMENT_DELETED_PHOTOLIST} must be present in a task. If {@value service.tut.pori.contentanalysis.Definitions#ELEMENT_DISSIMILAR_PHOTOLIST} or {@value service.tut.pori.contentanalysis.Definitions#ELEMENT_SIMILAR_PHOTOLIST} is present, {@value service.tut.pori.contentanalysis.Definitions#ELEMENT_REFERENCE_PHOTOLIST} must be present. 046 * 047 * When including {@link service.tut.pori.contentanalysis.SimilarPhotoList} and/or {@link service.tut.pori.contentanalysis.DissimilarPhotoList}, it is recommended to provide only a single reference photo in the {@link service.tut.pori.contentanalysis.ReferencePhotoList}, and the photos should not contain media objects with updated metadata (i.e. media object feedback). 048 * For the media object feedback, a separate feedback task should be generated. 049 * For tasks of type {@link service.tut.pori.contentanalysis.AsyncTask.TaskType#ANALYSIS} and {@link service.tut.pori.contentanalysis.AsyncTask.TaskType#BACKEND_FEEDBACK}, the valid list is {@link service.tut.pori.contentanalysis.PhotoList}, and for tasks of type {@link service.tut.pori.contentanalysis.AsyncTask.TaskType#FEEDBACK} the valid lists are {@link service.tut.pori.contentanalysis.DeletedPhotoList}, {@link service.tut.pori.contentanalysis.DissimilarPhotoList}, {@link service.tut.pori.contentanalysis.ReferencePhotoList} and {@link service.tut.pori.contentanalysis.SimilarPhotoList}. 050 * 051 * <h2>Optional Elements</h2> 052 * <ul> 053 * <li>{@value service.tut.pori.contentanalysis.Definitions#ELEMENT_BACKEND_STATUS_LIST}</li> 054 * <li>{@value service.tut.pori.contentanalysis.Definitions#ELEMENT_USER_CONFIDENCE}, recommended values are 0...1 normalized, though other values are also accepted.</li> 055 * </ul> 056 * 057 * <h3>XML Example - Analysis Task</h3> 058 * 059 * {@doc.restlet service="[service.tut.pori.contentanalysis.reference.Definitions#SERVICE_CA_REFERENCE_EXAMPLE]" method="[service.tut.pori.contentanalysis.Definitions#ELEMENT_TASK_DETAILS]" type="GET" query="[service.tut.pori.contentanalysis.reference.Definitions#PARAMETER_TASK_TYPE]=[service.tut.pori.contentanalysis.AsyncTask$TaskType#ANALYSIS]" body_uri=""} 060 * 061 * <h3>XML Example - Backend Feedback Task</h3> 062 * 063 * {@doc.restlet service="[service.tut.pori.contentanalysis.reference.Definitions#SERVICE_CA_REFERENCE_EXAMPLE]" method="[service.tut.pori.contentanalysis.Definitions#ELEMENT_TASK_DETAILS]" type="GET" query="[service.tut.pori.contentanalysis.reference.Definitions#PARAMETER_TASK_TYPE]=[service.tut.pori.contentanalysis.AsyncTask$TaskType#BACKEND_FEEDBACK]" body_uri=""} 064 * 065 * <h3>XML Example - Feedback Task</h3> 066 * 067 * {@doc.restlet service="[service.tut.pori.contentanalysis.reference.Definitions#SERVICE_CA_REFERENCE_EXAMPLE]" method="[service.tut.pori.contentanalysis.Definitions#ELEMENT_TASK_DETAILS]" type="GET" query="[service.tut.pori.contentanalysis.reference.Definitions#PARAMETER_TASK_TYPE]=[service.tut.pori.contentanalysis.AsyncTask$TaskType#FEEDBACK]" body_uri=""} 068 * 069 * @see service.tut.pori.contentanalysis.DeletedPhotoList 070 * @see service.tut.pori.contentanalysis.DissimilarPhotoList 071 * @see service.tut.pori.contentanalysis.SimilarPhotoList 072 * @see service.tut.pori.contentanalysis.PhotoList 073 * @see service.tut.pori.contentanalysis.ReferencePhotoList 074 */ 075@XmlRootElement(name=Definitions.ELEMENT_TASK_DETAILS) 076@XmlAccessorType(XmlAccessType.NONE) 077public final class PhotoTaskDetails extends AbstractTaskDetails{ 078 private PhotoParameters _analysisParameters = null; 079 @XmlElement(name = Definitions.ELEMENT_DELETED_PHOTOLIST) 080 private DeletedPhotoList _deletedPhotoList = null; 081 @XmlElement(name = Definitions.ELEMENT_DISSIMILAR_PHOTOLIST) 082 private DissimilarPhotoList _dissimilarPhotoList = null; 083 @XmlElement(name = Definitions.ELEMENT_PHOTOLIST) 084 private PhotoList _photoList = null; 085 @XmlElement(name = Definitions.ELEMENT_SIMILAR_PHOTOLIST) 086 private SimilarPhotoList _similarPhotoList = null; 087 @XmlElement(name = Definitions.ELEMENT_REFERENCE_PHOTOLIST) 088 private ReferencePhotoList _referencePhotoList = null; 089 @XmlElement(name = Definitions.ELEMENT_USER_CONFIDENCE) 090 private Double _userConfidence = null; 091 092 /** 093 * 094 * @return photo list 095 */ 096 public PhotoList getPhotoList() { 097 return _photoList; 098 } 099 100 /** 101 * 102 */ 103 public PhotoTaskDetails(){ 104 super(); 105 } 106 107 /** 108 * 109 * @param type 110 */ 111 public PhotoTaskDetails(TaskType type){ 112 super(); 113 setTaskType(type); 114 } 115 116 /** 117 * 118 * @param photoList 119 * @see #getPhotoList() 120 */ 121 public void setPhotoList(PhotoList photoList) { 122 _photoList = photoList; 123 } 124 125 /** 126 * 127 * @return list of deleted photos 128 * @see #setDeletedPhotoList(DeletedPhotoList) 129 */ 130 public DeletedPhotoList getDeletedPhotoList() { 131 return _deletedPhotoList; 132 } 133 134 /** 135 * 136 * @param deletedPhotoList 137 * @see #getDeletedPhotoList() 138 */ 139 public void setDeletedPhotoList(DeletedPhotoList deletedPhotoList) { 140 _deletedPhotoList = deletedPhotoList; 141 } 142 143 /** 144 * @see #getReferencePhotoList() 145 * @see #setSimilarPhotoList(SimilarPhotoList) 146 * 147 * @return list of photos similar to reference photos 148 */ 149 public SimilarPhotoList getSimilarPhotoList() { 150 return _similarPhotoList; 151 } 152 153 /** 154 * 155 * @param similarPhotoList 156 * @see #getSimilarPhotoList() 157 */ 158 public void setSimilarPhotoList(SimilarPhotoList similarPhotoList) { 159 _similarPhotoList = similarPhotoList; 160 } 161 162 /** 163 * @see #getReferencePhotoList() 164 * @see #setDissimilarPhotoList(DissimilarPhotoList) 165 * 166 * @return list of photos dissimilar to the reference photos 167 */ 168 public DissimilarPhotoList getDissimilarPhotoList() { 169 return _dissimilarPhotoList; 170 } 171 172 /** 173 * 174 * @param dissimilarPhotoList 175 * @see #getDissimilarPhotoList() 176 */ 177 public void setDissimilarPhotoList(DissimilarPhotoList dissimilarPhotoList) { 178 _dissimilarPhotoList = dissimilarPhotoList; 179 } 180 181 /** 182 * @see #getDissimilarPhotoList() 183 * @see #getSimilarPhotoList() 184 * @see #setReferencePhotoList(ReferencePhotoList) 185 * 186 * @return reference photos for similar and/or dissimilar photos 187 */ 188 public ReferencePhotoList getReferencePhotoList() { 189 return _referencePhotoList; 190 } 191 192 /** 193 * @param referencePhotoList the referencePhotoList to set 194 * @see #getReferencePhotoList() 195 */ 196 public void setReferencePhotoList(ReferencePhotoList referencePhotoList) { 197 _referencePhotoList = referencePhotoList; 198 } 199 200 /** 201 * 202 * @param photo 203 * @see #getReferencePhotoList() 204 */ 205 public void addReferencePhoto(Photo photo){ 206 if(_referencePhotoList == null){ 207 _referencePhotoList = new ReferencePhotoList(); 208 } 209 _referencePhotoList.addPhoto(photo); 210 } 211 212 /** 213 * 214 * @param photo 215 * @see #getPhotoList() 216 */ 217 public void addPhoto(Photo photo){ 218 if(_photoList == null){ 219 _photoList = new PhotoList(); 220 } 221 _photoList.addPhoto(photo); 222 } 223 224 /** 225 * 226 * @param photo 227 * @see #getDeletedPhotoList() 228 */ 229 public void addDeletedPhoto(Photo photo){ 230 if(_deletedPhotoList == null){ 231 _deletedPhotoList = new DeletedPhotoList(); 232 } 233 _deletedPhotoList.addPhoto(photo); 234 } 235 236 /** 237 * 238 * @param photo 239 * @see #getSimilarPhotoList() 240 */ 241 public void addSimilarPhoto(Photo photo){ 242 if(_similarPhotoList == null){ 243 _similarPhotoList = new SimilarPhotoList(); 244 } 245 _similarPhotoList.addPhoto(photo); 246 } 247 248 /** 249 * 250 * @param photo 251 * @see #getDissimilarPhotoList() 252 */ 253 public void addDissimilarPhoto(Photo photo){ 254 if(_dissimilarPhotoList == null){ 255 _dissimilarPhotoList = new DissimilarPhotoList(); 256 } 257 _dissimilarPhotoList.addPhoto(photo); 258 } 259 260 /** 261 * 262 * @return true if no photo lists are given or the lists are empty 263 */ 264 public boolean isEmpty(){ 265 if(!PhotoList.isEmpty(_photoList) || !ReferencePhotoList.isEmpty(_referencePhotoList) || !DeletedPhotoList.isEmpty(_deletedPhotoList) || !SimilarPhotoList.isEmpty(_similarPhotoList) || !DissimilarPhotoList.isEmpty(_dissimilarPhotoList)){ 266 return false; 267 }else{ 268 return true; 269 } 270 } 271 272 /** 273 * 274 * @return confidence of the task owner, or null if unknown 275 * @see #setUserConfidence(Double) 276 */ 277 public Double getUserConfidence() { 278 return _userConfidence; 279 } 280 281 /** 282 * 283 * @param userConfidence 284 * @see #getUserConfidence() 285 */ 286 public void setUserConfidence(Double userConfidence) { 287 _userConfidence = userConfidence; 288 } 289 290 @Override 291 public Map<String, String> getMetadata() { 292 if(_userConfidence == null){ 293 return super.getMetadata(); 294 }else{ 295 Map<String, String> metadata = super.getMetadata(); 296 if(metadata == null){ 297 metadata = new HashMap<>(1); 298 super.setMetadata(metadata); 299 } 300 metadata.put(Definitions.ELEMENT_CONFIDENCE, _userConfidence.toString()); 301 return metadata; 302 } 303 } 304 305 @Override 306 public void setMetadata(Map<String, String> metadata) { 307 if(metadata == null){ 308 _userConfidence = null; 309 }else{ 310 String confidence = metadata.get(Definitions.ELEMENT_CONFIDENCE); 311 if(StringUtils.isBlank(confidence)){ 312 _userConfidence = null; 313 }else{ 314 _userConfidence = Double.valueOf(confidence); 315 } 316 } 317 super.setMetadata(metadata); 318 } 319 320 @Override 321 public String getCallbackUri() { 322 String callbackUri = super.getCallbackUri(); 323 return (StringUtils.isBlank(callbackUri) ? generateFinishedCallbackUri() : callbackUri); 324 } 325 326 /** 327 * 328 * @return the default task finished callback uri 329 */ 330 public static String generateFinishedCallbackUri(){ 331 return ServiceInitializer.getPropertyHandler().getRESTBindContext()+Definitions.SERVICE_CA+"/"+Definitions.METHOD_TASK_FINISHED; 332 } 333 334 @Override 335 public PhotoParameters getTaskParameters() { 336 return _analysisParameters; 337 } 338 339 @Override 340 public void setTaskParameters(TaskParameters parameters) { 341 if(parameters == null){ 342 _analysisParameters = null; 343 }else if(parameters instanceof PhotoParameters){ 344 setTaskParameters((PhotoParameters) parameters); 345 }else{ 346 _analysisParameters = new PhotoParameters(); 347 } 348 } 349 350 /** 351 * 352 * @param parameters 353 */ 354 public void setTaskParameters(PhotoParameters parameters) { 355 _analysisParameters = parameters; 356 } 357}