package com.celements.photo.service;
import java.io.ByteArrayInputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;
import java.util.Vector;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.xwiki.component.annotation.Component;
import org.xwiki.component.annotation.Requirement;
import org.xwiki.context.Execution;
import org.xwiki.model.EntityType;
import org.xwiki.model.reference.AttachmentReference;
import org.xwiki.model.reference.DocumentReference;
import org.xwiki.model.reference.EntityReferenceResolver;
import org.xwiki.model.reference.WikiReference;
import com.celements.photo.container.ImageDimensions;
import com.celements.photo.image.GenerateThumbnail;
import com.celements.web.service.IWebUtilsService;
import com.celements.web.utils.WebUtils;
import com.xpn.xwiki.XWikiContext;
import com.xpn.xwiki.XWikiException;
import com.xpn.xwiki.api.Attachment;
import com.xpn.xwiki.api.Document;
import com.xpn.xwiki.doc.XWikiAttachment;
import com.xpn.xwiki.doc.XWikiDocument;
import com.xpn.xwiki.web.Utils;
@Component
public class ImageService implements IImageService {
private static final Log LOGGER = LogFactory.getFactory().getInstance(
ImageService.class);
@Requirement
Execution execution;
@Requirement
EntityReferenceResolver<String> stringRefResolver;
private XWikiContext getContext() {
return (XWikiContext) execution.getContext().getProperty("xwikicontext");
}
private DocumentReference getDocRefFromFullName(String collDocName) {
DocumentReference eventRef = new DocumentReference(stringRefResolver.resolve(
collDocName, EntityType.DOCUMENT));
eventRef.setWikiReference(new WikiReference(getContext().getDatabase()));
LOGGER.debug("getDocRefFromFullName: for [" + collDocName + "] got reference ["
+ eventRef + "].");
return eventRef;
}
public ImageDimensions getDimension(String imageFullName)
throws XWikiException {
String fullName = imageFullName.split(";")[0];
String imageFileName = imageFullName.split(";")[1];
DocumentReference docRef = getDocRefFromFullName(fullName);
AttachmentReference imgRef = new AttachmentReference(imageFileName, docRef);
return getDimension(imgRef);
}
public ImageDimensions getDimension(AttachmentReference imgRef) throws XWikiException {
DocumentReference docRef = (DocumentReference) imgRef.getParent();
XWikiDocument theDoc = getContext().getWiki().getDocument(docRef, getContext());
XWikiAttachment theAttachment = theDoc.getAttachment(imgRef.getName());
byte[] data;
try {
data = theAttachment.getContent(getContext());
} catch (XWikiException exp) {
LOGGER.warn("getDimension Image Attachment content [" + theAttachment.getFilename()
+ "] not found.", exp);
Object[] args = { theAttachment.getFilename() };
throw new XWikiException(XWikiException.MODULE_XWIKI_APP,
XWikiException.ERROR_XWIKI_APP_ATTACHMENT_NOT_FOUND,
"Attachment content {0} not found", exp, args);
}
GenerateThumbnail genThumbnail = new GenerateThumbnail();
ByteArrayInputStream imageInStream = new ByteArrayInputStream(data);
ImageDimensions imageDimensions = genThumbnail.getImageDimensions(imageInStream);
imageInStream.reset();
return imageDimensions;
}
/**
* getRandomImages computes a set of <num> randomly chosen images
* from the given AttachmentList. It chooses the Images without duplicates if
* possible.
*/
public List<Attachment> getRandomImages(DocumentReference galleryRef, int num) {
try {
Document imgDoc = getContext().getWiki().getDocument(galleryRef, getContext()
).newDocument(getContext());
List<Attachment> allImagesList = getWebUtilsService().getAttachmentListSorted(imgDoc,
"AttachmentAscendingNameComparator", true);
if (allImagesList.size() > 0) {
List<Attachment> preSetImgList = prepareMaxCoverSet(num, allImagesList);
List<Attachment> imgList = new ArrayList<Attachment>(num);
Random rand = new Random();
for (int i=1; i<=num ; i++) {
int nextimg = rand.nextInt(preSetImgList.size());
imgList.add(preSetImgList.remove(nextimg));
}
return imgList;
}
} catch (XWikiException e) {
LOGGER.error(e);
}
return Collections.emptyList();
}
<T> List<T> prepareMaxCoverSet(int num, List<T> allImagesList) {
List<T> preSetImgList = new Vector<T>(num);
preSetImgList.addAll(allImagesList);
for(int i=2; i <= coveredQuotient(allImagesList.size(), num); i++) {
preSetImgList.addAll(allImagesList);
}
return preSetImgList;
}
int coveredQuotient(int divisor, int dividend) {
if (dividend >= 0) {
return ( (dividend + divisor - 1) / divisor);
} else {
return (dividend / divisor);
}
}
private IWebUtilsService getWebUtilsService() {
return Utils.getComponent(IWebUtilsService.class);
}
}