package org.rr.jeborker.metadata; import java.io.IOException; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.util.List; import org.rr.commons.log.LoggerFactory; import org.rr.commons.mufs.IResourceHandler; import org.rr.commons.mufs.ResourceHandlerFactory; import org.rr.commons.utils.StringUtil; import org.rr.jeborker.app.FileRefreshBackground; import org.rr.jeborker.metadata.IMetadataReader.COMMON_METADATA_TYPES; import org.rr.mobi4java.MobiDocument; import org.rr.mobi4java.MobiMetaData; import org.rr.mobi4java.MobiReader; import org.rr.mobi4java.MobiWriter; public class MobiMetadataWriter implements IMetadataWriter { private IResourceHandler ebookResource; public MobiMetadataWriter(IResourceHandler ebookResource) { this.ebookResource = ebookResource; } @Override public void writeMetadata(List<MetadataProperty> props) { try { FileRefreshBackground.setDisabled(true); MobiDocument mobiDoc = new MobiReader().read(ebookResource.getContentInputStream()); MobiMetaData metaData = mobiDoc.getMetaData(); metaData.removeAllEXTHRecords(); applyChanges(props, mobiDoc, metaData); writeBook(mobiDoc); } catch (Exception e) { LoggerFactory.logWarning(this, "could not write pdf meta data for " + ebookResource, e); } finally { FileRefreshBackground.setDisabled(false); } } private void applyChanges(List<MetadataProperty> props, MobiDocument mobiDoc, MobiMetaData metaData) throws UnsupportedEncodingException { for (MetadataProperty prop : props) { if (StringUtil.equalsIgnoreCase(prop.getName(), "title")) { mobiDoc.setFullName(prop.getValueAsString()); } else if (StringUtil.equals(prop.getName(), COMMON_METADATA_TYPES.COVER.getName())) { mobiDoc.setCover((byte[]) prop.getValues().get(0)); } else if(prop instanceof MobiMetadataProperty) { metaData.addEXTHRecord(((MobiMetadataProperty)prop).getExthRecord()); } else { LoggerFactory.logWarning(this.getClass(), "Unkown property " + prop.getName() + " in " + ebookResource); } } } protected void writeBook(MobiDocument mobiDoc) throws IOException { IResourceHandler temporaryResourceLoader = ResourceHandlerFactory.getUniqueResourceHandler(ebookResource, "tmp"); try (OutputStream out = temporaryResourceLoader.getContentOutputStream(false);) { new MobiWriter().write(mobiDoc, out); if (temporaryResourceLoader.size() > 0) { temporaryResourceLoader.moveTo(ebookResource, true); } else { temporaryResourceLoader.delete(); } } } @Override public void storePlainMetadata(byte[] plainMetadata) { throw new UnsupportedOperationException("Plain meta data is not supported with mobi."); } }