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 018import java.util.ArrayList; 019import java.util.Collection; 020import java.util.Iterator; 021import java.util.List; 022 023import javax.xml.bind.annotation.XmlAccessType; 024import javax.xml.bind.annotation.XmlAccessorType; 025import javax.xml.bind.annotation.XmlElement; 026import javax.xml.bind.annotation.XmlRootElement; 027 028import org.apache.log4j.Logger; 029 030import core.tut.pori.http.ResponseData; 031 032/** 033 * 034 * This is a container class for photo elements, which can be used directly with Response to provide XML output. 035 * 036 * <h3>XML Example</h3> 037 * 038 * {@doc.restlet service="[service.tut.pori.contentanalysis.reference.Definitions#SERVICE_CA_REFERENCE_EXAMPLE]" method="[service.tut.pori.contentanalysis.Definitions#ELEMENT_PHOTOLIST]" type="GET" query="" body_uri=""} 039 * 040 * @see service.tut.pori.contentanalysis.Photo 041 * @see service.tut.pori.contentanalysis.ResultInfo 042 */ 043@XmlRootElement(name=Definitions.ELEMENT_PHOTOLIST) 044@XmlAccessorType(value=XmlAccessType.NONE) 045public class PhotoList extends ResponseData{ 046 private static final Logger LOGGER = Logger.getLogger(PhotoList.class); 047 @XmlElement(name = Definitions.ELEMENT_PHOTO) 048 private List<Photo> _photos = null; 049 @XmlElement(name = Definitions.ELEMENT_RESULT_INFO) 050 private ResultInfo _resultInfo = null; 051 052 /** 053 * @return list of photos 054 * @see #setPhotos(List) 055 */ 056 public List<Photo> getPhotos() { 057 if(_photos == null || _photos.isEmpty()){ 058 return null; 059 }else{ 060 return _photos; 061 } 062 } 063 064 /** 065 * 066 * @return list of GUIDs in this list or null if the list contains no GUIDs. 067 */ 068 public List<String> getGUIDs(){ 069 return getGUIDs(this); 070 } 071 072 /** 073 * 074 * @param photoList 075 * @return GUIDs contained in the given photo list or null if none. Photos without GUIDs will be ignored. 076 */ 077 public static List<String> getGUIDs(PhotoList photoList){ 078 if(isEmpty(photoList)){ 079 LOGGER.debug("Empty photo list."); 080 return null; 081 }else{ 082 List<Photo> photos = photoList.getPhotos(); 083 List<String> guids = new ArrayList<>(photos.size()); 084 for(Iterator<Photo> iter = photos.iterator(); iter.hasNext();){ 085 String guid = iter.next().getGUID(); 086 if(guid == null){ 087 LOGGER.debug("Skipped photo without GUID."); 088 }else{ 089 guids.add(guid); 090 } 091 } 092 return (guids.isEmpty() ? null : guids); 093 } 094 } 095 096 /** 097 * 098 * @return resultInfo or null if not available 099 * @see #setResultInfo(ResultInfo) 100 */ 101 public ResultInfo getResultInfo(){ 102 return _resultInfo; 103 } 104 105 /** 106 * 107 * @param resultInfo 108 * @see #getResultInfo() 109 */ 110 public void setResultInfo(ResultInfo resultInfo){ 111 _resultInfo = resultInfo; 112 } 113 114 /** 115 * 116 * replace the currently set set of photos with a new set of photos 117 * @param photos 118 * @see #getPhotos() 119 */ 120 public void setPhotos(List<Photo> photos) { 121 _photos = photos; 122 } 123 124 /** 125 * 126 * @param photo 127 * @see #getPhotos() 128 */ 129 public void addPhoto(Photo photo) { 130 if(_photos == null){ 131 _photos = new ArrayList<>(); 132 } 133 _photos.add(photo); 134 } 135 136 /** 137 * 138 * @param photos 139 * @see #getPhotos() 140 */ 141 public void addPhotos(PhotoList photos){ 142 if(PhotoList.isEmpty(photos)){ 143 LOGGER.debug("Ignored empty photo list."); 144 return; 145 } 146 if(_photos == null){ 147 _photos = new ArrayList<>(photos.getPhotos()); 148 }else{ 149 _photos.addAll(photos.getPhotos()); 150 } 151 } 152 153 /** 154 * 155 * NOTE: to use getPhotoList factory functions, the nullary constructor of the inherited class MUST be available 156 */ 157 public PhotoList(){ 158 // nothing needed 159 } 160 161 /** 162 * 163 * @param guid 164 * @return photo with the given guid or null if not in the list 165 */ 166 public Photo getPhoto(String guid){ 167 if(isEmpty()){ 168 return null; 169 } 170 if(guid == null){ 171 LOGGER.debug("Ignored null GUID."); 172 return null; 173 } 174 for(Iterator<Photo> iter = _photos.iterator(); iter.hasNext();){ 175 Photo p = iter.next(); 176 if(guid.equals(p.getGUID())){ 177 return p; 178 } 179 } 180 return null; 181 } 182 183 /** 184 * 185 * @param photos 186 * @param resultInfo optional resultInfo 187 * @return new photo list of null if null or empty photos given 188 */ 189 public static PhotoList getPhotoList(Collection<Photo> photos, ResultInfo resultInfo){ 190 if(photos == null || photos.isEmpty()){ 191 return null; 192 } 193 194 PhotoList photoList = new PhotoList(); 195 photoList.setPhotos(new ArrayList<>(photos)); 196 photoList.setResultInfo(resultInfo); 197 return photoList; 198 } 199 200 /** 201 * @param list 202 * @return true if the given list is empty or null 203 */ 204 public static boolean isEmpty(PhotoList list){ 205 if(list == null || list.isEmpty()){ 206 return true; 207 }else{ 208 return false; 209 } 210 } 211 212 /** 213 * use the static, only for sub-classing 214 * @return true if this list is empty 215 * @see #isEmpty(PhotoList) 216 */ 217 protected boolean isEmpty(){ 218 if(_photos == null || _photos.isEmpty()){ 219 return true; 220 }else{ 221 return false; 222 } 223 } 224 225 /** 226 * 227 * @param list can be null 228 * @return true if the given list is valid 229 */ 230 public static boolean isValid(PhotoList list){ 231 if(list == null){ 232 return false; 233 }else{ 234 return list.isValid(); 235 } 236 } 237 238 /** 239 * use the static, only for sub-classing 240 * @return true if this list is valid 241 * @see #isValid(PhotoList) 242 */ 243 protected boolean isValid(){ 244 if(isEmpty()){ 245 return false; 246 }else{ 247 for(Iterator<Photo> iter = _photos.iterator();iter.hasNext();){ 248 if(!Photo.isValid(iter.next())){ 249 return false; 250 } 251 } 252 return true; 253 } 254 } 255 256 /** 257 * use the static, only for sub-classing 258 * @return number of photos in the list 259 * @see #count(PhotoList) 260 */ 261 protected int count(){ 262 return (_photos == null ? 0 : _photos.size()); 263 } 264 265 /** 266 * 267 * @param list 268 * @return number of photos in the list or 0 if null or empty list passed 269 */ 270 public static int count(PhotoList list){ 271 return (list == null ? 0 : list.count()); 272 } 273}