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}