/* * See the NOTICE file distributed with this work for additional * information regarding copyright ownership. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package com.celements.photo.metadata; import java.io.IOException; import java.io.InputStream; import java.util.Collections; import java.util.Enumeration; import java.util.Hashtable; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Vector; import com.celements.photo.container.ImageLibStrings; import com.celements.photo.container.Metadate; import com.celements.photo.utilities.BaseObjectHandler; import com.celements.photo.utilities.ZipAttachmentChanges; import com.drew.metadata.MetadataException; import com.xpn.xwiki.XWikiContext; import com.xpn.xwiki.XWikiException; import com.xpn.xwiki.doc.XWikiDocument; import com.xpn.xwiki.objects.BaseObject; /** * Provides methods to access metadata. */ @Deprecated public class Metainfo { /** * Get a specified Metadate from an image. * * @param doc XWikiDocument of the album. * @param id Hashcode of the image. * @param imageMethods Used to get the image. * @param tag Name of the metatag to get. * @param context XWikiContext * @return The Metadate of the specified Tag. * @throws XWikiException * @throws MetadataException * @throws IOException */ public Metadate getTag(XWikiDocument doc, String id, String tag, XWikiContext context) throws XWikiException, MetadataException, IOException { List<BaseObject> metainfos = getMetadataList(doc, id, context); Metadate metatag = new Metadate(); for (int i = 0; i < metainfos.size(); i++) { BaseObject metadate = (BaseObject) metainfos.get(i); if((metadate != null) && (metadate.getStringValue(ImageLibStrings.METAINFO_CLASS_NAME).equals(tag))){ metatag = new Metadate(metadate.getStringValue(ImageLibStrings.METAINFO_CLASS_NAME), metadate.getStringValue(ImageLibStrings.METAINFO_CLASS_DESCRIPTION)); break; } } return metatag; } /** * Returns an array of Metadate objects, excluding the tags starting with * the specified condition. If the condition is an empty String or null the * all metadata available is returned. * * @param doc XWikiDocument of the album. * @param id Hashcode of the image. * @param conditionTag Tags starting with this String are excluded from the result List. * @param imageMethods Used to get the image. * @param context XWikiContext * @return Array of Metadate objects. * @throws XWikiException * @throws MetadataException * @throws IOException */ public Metadate[] getMetadataWithCondition(XWikiDocument doc, String id, String conditionTag, XWikiContext context) throws XWikiException, MetadataException, IOException { List<BaseObject> metainfos = getMetadataList(doc, id, context); List<Metadate> resultList = new Vector<Metadate>(); boolean condition = false; if((conditionTag == null) || conditionTag.equals("")){ condition = true; } getAvailableNotExcludedTags(conditionTag, condition, metainfos, resultList); return resultList.toArray(new Metadate[resultList.size()]); } private void getAvailableNotExcludedTags(String conditionTag, boolean condition, List<BaseObject> metainfos, List<Metadate> resultList) { for (Iterator<BaseObject> iter = metainfos.iterator(); iter.hasNext();) { BaseObject metadate = (BaseObject) iter.next(); if((metadate != null) && (condition || !metadate.getStringValue(ImageLibStrings.METAINFO_CLASS_NAME).startsWith(conditionTag))){ resultList.add(new Metadate(metadate.getStringValue(ImageLibStrings.METAINFO_CLASS_NAME), metadate.getStringValue(ImageLibStrings.METAINFO_CLASS_DESCRIPTION))); } } } /** * Get all metainformation contained in a specified image. * * @param doc XWikiDocument of the album. * @param id Hashcode of the image. * @param imageMethods Used to get the image. * @param context XWikiContext * @return A List containing all the metadata from the specified image. * @throws XWikiException * @throws MetadataException * @throws IOException */ public List<BaseObject> getMetadataList(XWikiDocument doc, String id, XWikiContext context) throws XWikiException, MetadataException, IOException { extractMetaToDoc(doc, id, context); XWikiDocument metaDoc = context.getWiki().getDocument(ImageLibStrings.getPhotoSpace(doc), doc.getName() + ImageLibStrings.DOCUMENT_SEPARATOR_IMAGE + id, context); List<BaseObject> metainfos = metaDoc.getObjects(ImageLibStrings.METAINFO_CLASS); //return an empty List if no metainfo objects are attached. if(metainfos == null){ metainfos = java.util.Collections.emptyList(); } return metainfos; } /** * Extract metadata from an image and write it to objects, attached to a * XWikiDocument. * * @param doc XWikiDocument of the album. * @param id Hashcode of the image. * @param imageMethods Used to get the image. * @param context XWikiContext * @throws XWikiException * @throws MetadataException * @throws IOException */ public void extractMetaToDoc(XWikiDocument doc, String id, XWikiContext context) throws XWikiException, MetadataException, IOException{ String album = doc.getName(); XWikiDocument celeMeta = context.getWiki().getDocument(ImageLibStrings.getPhotoSpace(doc), album + ImageLibStrings.DOCUMENT_SEPARATOR_IMAGE + id, context); String dir = (new BaseObjectHandler()).getImageString(celeMeta, ImageLibStrings.PHOTO_IMAGE_ZIPDIRECTORY); String image = (new BaseObjectHandler()).getImageString(celeMeta, ImageLibStrings.PHOTO_IMAGE_FILENAME); if(image == null){ (new ZipAttachmentChanges()).checkZipAttatchmentChanges(doc, context); } clearOutdatedMetadata(doc, id, context); // TODO ugly, but otherwise updating files seems not to work properly context.getWiki().flushCache(context); List<BaseObject> metadataObjs = celeMeta.getObjects(ImageLibStrings.METAINFO_CLASS); if(metadataObjs == null || metadataObjs.size() == 0){ Map<String, String> metadata = extractAllMetadata(doc, dir + image, id, context); for(String key : metadata.keySet()) { initNewObject(celeMeta, key, (String)metadata.get(key), context); } //If there is no metadata, this prevents from trying to extract metadata on each image load. if(metadata.size() == 0){ celeMeta.newObject(ImageLibStrings.METAINFO_CLASS, context); } context.getWiki().saveDocument(celeMeta, context); } } private void initNewObject(XWikiDocument celeMeta, String key, String value, XWikiContext context) throws XWikiException { BaseObject metainfoObj = celeMeta.newObject(ImageLibStrings.METAINFO_CLASS, context); metainfoObj.set(ImageLibStrings.METAINFO_CLASS_NAME, key, context); metainfoObj.set(ImageLibStrings.METAINFO_CLASS_DESCRIPTION, value, context); } /** * Extracts all metadata directories of an image and returns them in a * Hashtable. * * @param albumDoc XWikiDocument of the album. * @param image Name of the image. * @param id Id of the image. * @param imageMethods Used to get the image. * @param context XWikiContext * @return Hashtable containing all the metadata extracted from the image. * @throws MetadataException * @throws XWikiException * @throws IOException */ @SuppressWarnings("unchecked") private Map<String, String> extractAllMetadata(XWikiDocument albumDoc, String image, String id, XWikiContext context) throws MetadataException, XWikiException, IOException{ InputStream imgAttachment = (new ZipAttachmentChanges()).getFromZip(albumDoc, image, id, context); if(imgAttachment != null){ return (new MetaInfoExtractor()).getAllTags(imgAttachment); } return new Hashtable(Collections.emptyMap()); } /** * Deletes the document with the metadata attached if it is older than its * image (only the metadata extracted from the image is deleted, but not * the data generated by CelementsPhotoPlugin). * * @param doc XWikiDocument of the album. * @param image Name of the image the metadata belongs to. * @param imageMethods To be able to get the original image from its zip * archive. * @param context XWikiContext * @throws XWikiException * @throws IOException */ private void clearOutdatedMetadata(XWikiDocument doc, String id, XWikiContext context) throws XWikiException, IOException{ XWikiDocument metadataDoc = context.getWiki().getDocument(ImageLibStrings.getPhotoSpace(doc), doc.getName() + ImageLibStrings.DOCUMENT_SEPARATOR_IMAGE + id, context); if(!metadataDoc.isNew()){ com.xpn.xwiki.doc.XWikiAttachment containingZip = (new ZipAttachmentChanges()).getContainingZip(doc, id, context); java.util.Date metaDate = metadataDoc.getDate(); java.util.Date zipDate = containingZip.getDate(); if(metaDate.before(zipDate)){ metadataDoc.removeObjects(ImageLibStrings.METAINFO_CLASS); context.getWiki().saveDocument(metadataDoc, context); } } } }