/*
* Copyright (c) 2006-2009 by Dirk Riehle, http://dirkriehle.com
*
* This file is part of the Wahlzeit photo rating application.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/>.
*/
package org.wahlzeit.model;
import org.wahlzeit.services.LogBuilder;
import org.wahlzeit.utils.StringUtil;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;
import java.util.logging.Logger;
/**
* A class to specify a photo filter.
* A photo filter captures selection ("filtering") criteria for photos.
*/
public class PhotoFilter implements Serializable {
private static Logger log = Logger.getLogger(PhotoFilter.class.getName());
/**
*
*/
public static final String USER_NAME = "userName";
public static final String TAGS = "tags";
/**
*
*/
protected String userName = "";
protected Tags tags = Tags.EMPTY_TAGS;
/**
*
*/
protected List<PhotoId> displayablePhotoIds;
protected List<PhotoId> processedPhotoIds = new LinkedList<PhotoId>();
protected List<PhotoId> skippedPhotoIds = new LinkedList<PhotoId>();
/**
*
*/
protected Random randomNumber = new Random(System.currentTimeMillis());
/**
*
*/
public PhotoFilter() {
resetDisplayablePhotoIds();
}
/**
*
*/
public String getUserName() {
return userName;
}
/**
*
*/
public void clear() {
setUserName("");
setTags(Tags.EMPTY_TAGS);
displayablePhotoIds.clear();
processedPhotoIds.clear();
}
/**
*
*/
public void setUserName(String newUserName) {
userName = newUserName;
resetDisplayablePhotoIds();
}
/**
*
*/
public Tags getTags() {
return tags;
}
/**
*
*/
public void setTags(Tags newTags) {
tags = newTags;
resetDisplayablePhotoIds();
}
/**
*
*/
public List<String> getFilterConditions() {
List<String> filterConditions = new ArrayList<String>();
collectFilterConditions(filterConditions);
return filterConditions;
}
/**
*
*/
protected void collectFilterConditions(List<String> filterConditions) {
String un = getUserName();
if (!StringUtil.isNullOrEmptyString(un)) {
filterConditions.add("un:" + Tags.asTag(un));
}
String[] tags = getTags().asArray();
for (int i = 0; i < tags.length; i++) {
filterConditions.add("tg:" + tags[i]);
}
}
/**
* @methodtype command
*/
public void generateDisplayablePhotoIds() {
displayablePhotoIds = getFilteredPhotoIds();
}
/**
* Get a random photo that has not been rated. If possible avoid skipped photos.
*/
public PhotoId getRandomDisplayablePhotoId() {
if (!displayablePhotoIds.isEmpty()) {
int size = displayablePhotoIds.size();
int index = ((randomNumber.nextInt() % size) + size) / 2;
return displayablePhotoIds.get(index);
} else {
return PhotoId.NULL_ID;
}
}
/**
*
*/
public List<PhotoId> getDisplayablePhotoIds() {
return displayablePhotoIds;
}
/**
*
*/
public void setDisplayablePhotoIds(List<PhotoId> newPhotoIds) {
displayablePhotoIds = newPhotoIds;
}
/**
*
*/
public void resetDisplayablePhotoIds() {
displayablePhotoIds = new ArrayList<PhotoId>();
}
/**
*
*/
public List<PhotoId> getProcessedPhotoIds() {
return processedPhotoIds;
}
/**
*
*/
public boolean isProcessedPhotoId(PhotoId photoId) {
log.info("photoId: " + photoId.asString());
for (PhotoId id : processedPhotoIds) {
log.info("Processed id: " + id.asString());
}
return processedPhotoIds.contains(photoId);
}
/**
*
*/
public void addProcessedPhoto(Photo photo) {
PhotoId photoId = photo.getId();
processedPhotoIds.add(photoId);
skippedPhotoIds.remove(photoId);
if (displayablePhotoIds != null) {
displayablePhotoIds.remove(photoId);
}
}
/**
* @methodtype get
*/
public List<PhotoId> getSkippedPhotoIds() {
return skippedPhotoIds;
}
/**
* @methodtype set
*/
public void setSkippedPhotoIds(List<PhotoId> skippedPhotoIds) {
this.skippedPhotoIds = skippedPhotoIds;
}
/**
* @methodtype set
*/
public void addSkippedPhotoId(PhotoId skippedPhotoId) {
if (!skippedPhotoIds.contains(skippedPhotoId)) {
skippedPhotoIds.add(skippedPhotoId);
}
}
/**
*
*/
protected List<PhotoId> getFilteredPhotoIds() {
// get all tags that match the filter conditions
List<PhotoId> result = new LinkedList<PhotoId>();
int noFilterConditions = getFilterConditions().size();
log.config(LogBuilder.createSystemMessage().
addParameter("Number of filter conditions", String.valueOf(noFilterConditions)).toString());
Collection<PhotoId> candidates;
if (noFilterConditions == 0) {
candidates = PhotoManager.getInstance().getPhotoCache().keySet();
} else {
List<Tag> tags = new LinkedList<Tag>();
candidates = new LinkedList<PhotoId>();
for (String condition : getFilterConditions()) {
PhotoManager.getInstance().addTagsThatMatchCondition(tags, condition);
}
// get the list of all photo ids that correspond to the tags
for (Tag tag : tags) {
candidates.add(PhotoId.getIdFromString(tag.getPhotoId()));
}
}
int newPhotos = 0;
for (PhotoId candidateId : candidates) {
Photo photoCandidate = PhotoManager.getInstance().getPhoto(candidateId);
if (!processedPhotoIds.contains(candidateId) && !skippedPhotoIds.contains(candidateId) &&
photoCandidate.isVisible()) {
result.add(candidateId);
++newPhotos;
}
}
int skippedPhotos = skippedPhotoIds.size();
if (newPhotos == 0 && skippedPhotos > 0) {
result.addAll(skippedPhotoIds);
newPhotos = skippedPhotos;
}
log.config(LogBuilder.createSystemMessage().addParameter("Number of photos to show", newPhotos)
.toString());
return result;
}
}