001/*
002 * (C) Copyright 2006-2008 Nuxeo SAS (http://nuxeo.com/) and contributors.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the GNU Lesser General Public License
006 * (LGPL) version 2.1 which accompanies this distribution, and is available at
007 * http://www.gnu.org/licenses/lgpl.html
008 *
009 * This library is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012 * Lesser General Public License for more details.
013 *
014 * Contributors:
015 *     Nuxeo - initial API and implementation
016 *
017 * $Id$
018 *
019 */
020package org.nuxeo.ecm.platform.pictures.tiles.api;
021
022import java.io.File;
023import java.io.IOException;
024import java.io.Serializable;
025import java.util.Map;
026
027import org.nuxeo.common.utils.Path;
028import org.nuxeo.ecm.core.api.Blob;
029import org.nuxeo.ecm.core.api.Blobs;
030import org.nuxeo.ecm.core.api.NuxeoException;
031import org.nuxeo.ecm.core.api.impl.blob.FileBlob;
032import org.nuxeo.ecm.platform.picture.api.ImageInfo;
033import org.nuxeo.ecm.platform.pictures.tiles.helpers.StringMaker;
034import org.nuxeo.runtime.api.Framework;
035
036/**
037 * Default implementation for the PictureTiles interface
038 *
039 * @author tiry
040 */
041public class PictureTilesImpl implements PictureTiles, Serializable {
042
043    /**
044     *
045     */
046    private static final long serialVersionUID = 1L;
047
048    public static String TILE_OUTPUT_DIR_KEY = "outputDirPath";
049
050    public static String TILE_INPUT_FILE_KEY = "inputFilePath";
051
052    public static String X_TILES_KEY = "XTiles";
053
054    public static String Y_TILES_KEY = "YTiles";
055
056    public static String LAST_MODIFICATION_DATE_KEY = "lastModificationDate";
057
058    // public static String ZoomFactorKey = "ZoomFactor";
059    public static String TILES_PREFIX_KEY = "TilesPrefix";
060
061    public static String TILES_SUFFIX_KEY = "TilesSuffix";
062
063    public static String TILES_WIDTH_KEY = "TilesWidth";
064
065    public static String TILES_HEIGHT_KEY = "TilesHeight";
066
067    public static String MAX_TILES_KEY = "MaxTiles";
068
069    public static String PROGRESSIVE_TILING_KEY = "ProgressiveTiling";
070
071    protected Map<String, String> infoMap;
072
073    protected String tilesDirPath;
074
075    protected String cacheKey;
076
077    protected ImageInfo sourceImageInfo;
078
079    protected ImageInfo originalImageInfo;
080
081    public PictureTilesImpl(String tilesDirPath) {
082        this.tilesDirPath = tilesDirPath;
083    }
084
085    public PictureTilesImpl(Map<String, String> info) {
086        infoMap = info;
087        tilesDirPath = info.get(TILE_OUTPUT_DIR_KEY);
088    }
089
090    public String getCacheKey() {
091        return cacheKey;
092    }
093
094    public void setCacheKey(String cacheKey) {
095        this.cacheKey = cacheKey;
096    }
097
098    public Map<String, String> getInfo() {
099        return infoMap;
100    }
101
102    public boolean isTileComputed(int x, int y) {
103        long lastModificationTime = Long.parseLong(infoMap.get(PictureTilesImpl.LAST_MODIFICATION_DATE_KEY));
104        String tileFileName = StringMaker.getTileFileName(x, y, infoMap.get(TILES_PREFIX_KEY),
105                infoMap.get(TILES_SUFFIX_KEY), lastModificationTime);
106        File imageFile = new File(tilesDirPath + tileFileName);
107        return imageFile.exists();
108    }
109
110    public Blob getTile(int x, int y) throws IOException {
111        String imageFilePath = getTileFilePath(x, y);
112        File imageFile = new File(imageFilePath);
113        if (imageFile.exists())
114            return Blobs.createBlob(imageFile);
115        else {
116            PictureTilingService pts = Framework.getService(PictureTilingService.class);
117            pts.completeTiles(this, x, y);
118            imageFile = new File(imageFilePath);
119            if (imageFile.exists())
120                return Blobs.createBlob(imageFile);
121            else
122                throw new NuxeoException("Unable to get Tile");
123        }
124    }
125
126    public String getTileFilePath(int x, int y) {
127        long lastModificationTime = Long.parseLong(infoMap.get(PictureTilesImpl.LAST_MODIFICATION_DATE_KEY));
128        String tileFileName = StringMaker.getTileFileName(x, y, infoMap.get(TILES_PREFIX_KEY),
129                infoMap.get(TILES_SUFFIX_KEY), lastModificationTime);
130        String imageFilePath = new Path(tilesDirPath).append(tileFileName).toString();
131        return imageFilePath;
132    }
133
134    public int getMaxTiles() {
135        String MT = infoMap.get(MAX_TILES_KEY);
136        if (MT == null) {
137            return 0;
138        }
139        return Integer.parseInt(MT);
140    }
141
142    public int getTilesWidth() {
143        String TW = infoMap.get(TILES_WIDTH_KEY);
144        if (TW == null) {
145            return 0;
146        }
147        return Integer.parseInt(TW);
148    }
149
150    public int getTilesHeight() {
151        String TH = infoMap.get(TILES_HEIGHT_KEY);
152        if (TH == null) {
153            return 0;
154        }
155        return Integer.parseInt(TH);
156    }
157
158    public String getTilesPath() {
159        return tilesDirPath;
160    }
161
162    public int getXTiles() {
163        String XT = infoMap.get(X_TILES_KEY);
164        if (XT == null) {
165            return 0;
166        }
167        return Integer.parseInt(XT);
168    }
169
170    public int getYTiles() {
171        String YT = infoMap.get(Y_TILES_KEY);
172        if (YT == null) {
173            return 0;
174        }
175        return Integer.parseInt(YT);
176    }
177
178    public float getZoomfactor() {
179
180        float oWith = originalImageInfo.getWidth();
181        float tWith = getXTiles() * getTilesWidth();
182        float oHeight = originalImageInfo.getHeight();
183        float tHeight = getYTiles() * getTilesHeight();
184        return tWith / oWith < tHeight / oHeight ? tWith / oWith : tHeight / oHeight;
185    }
186
187    public void release() {
188        long lastModificationTime = Long.parseLong(infoMap.get(PictureTilesImpl.LAST_MODIFICATION_DATE_KEY));
189        for (int x = 0; x < getXTiles(); x++) {
190            for (int y = 0; y < getYTiles(); y++) {
191                String tileFileName = StringMaker.getTileFileName(x, y, infoMap.get(TILES_PREFIX_KEY),
192                        infoMap.get(TILES_SUFFIX_KEY), lastModificationTime);
193                File img = new File(tilesDirPath + tileFileName);
194                if (img.exists())
195                    img.delete();
196            }
197        }
198    }
199
200    public ImageInfo getSourceImageInfo() {
201        return sourceImageInfo;
202    }
203
204    public void setSourceImageInfo(ImageInfo imageInfo) {
205        this.sourceImageInfo = imageInfo;
206    }
207
208    public String getTileFormatCacheKey() {
209        return StringMaker.getTileFormatString(getTilesWidth(), getTilesHeight(), getMaxTiles());
210    }
211
212    public ImageInfo getOriginalImageInfo() {
213        return originalImageInfo;
214    }
215
216    public void setOriginalImageInfo(ImageInfo imageInfo) {
217        originalImageInfo = imageInfo;
218    }
219
220}