blob: 12b8e590c0b71cff7d72ee511d7b19089b61431c [file] [log] [blame]
/*
* Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/** $Id$ */
package org.intellij.images.vfs;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ProjectFileIndex;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.reference.SoftReference;
import com.intellij.util.LogicalRoot;
import com.intellij.util.LogicalRootsManager;
import org.apache.sanselan.ImageReadException;
import org.apache.sanselan.common.byteSources.ByteSourceArray;
import org.apache.sanselan.formats.ico.IcoImageParser;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.imageio.ImageIO;
import javax.imageio.ImageReadParam;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;
/**
* Image loader utility.
*
* @author <a href="mailto:aefimov.box@gmail.com">Alexey Efimov</a>
*/
public final class IfsUtil {
public static final String ICO_FORMAT = "ico";
private static final Key<Long> TIMESTAMP_KEY = Key.create("Image.timeStamp");
private static final Key<String> FORMAT_KEY = Key.create("Image.format");
private static final Key<SoftReference<BufferedImage>> BUFFERED_IMAGE_REF_KEY = Key.create("Image.bufferedImage");
private static final IcoImageParser ICO_IMAGE_PARSER = new IcoImageParser();
/**
* Load image data for file and put user data attributes into file.
*
* @param file File
* @return true if file image is loaded.
* @throws java.io.IOException if image can not be loaded
*/
private static boolean refresh(@NotNull VirtualFile file) throws IOException {
Long loadedTimeStamp = file.getUserData(TIMESTAMP_KEY);
SoftReference<BufferedImage> imageRef = file.getUserData(BUFFERED_IMAGE_REF_KEY);
if (loadedTimeStamp == null || loadedTimeStamp.longValue() != file.getTimeStamp() || SoftReference.dereference(imageRef) == null) {
try {
final byte[] content = file.contentsToByteArray();
if (ICO_FORMAT.equalsIgnoreCase(file.getExtension())) {
try {
final BufferedImage image = ICO_IMAGE_PARSER.getBufferedImage(new ByteSourceArray(content), null);
file.putUserData(FORMAT_KEY, ICO_FORMAT);
file.putUserData(BUFFERED_IMAGE_REF_KEY, new SoftReference<BufferedImage>(image));
return true;
}
catch (ImageReadException ignore) { }
}
InputStream inputStream = new ByteArrayInputStream(content, 0, content.length);
ImageInputStream imageInputStream = ImageIO.createImageInputStream(inputStream);
try {
Iterator<ImageReader> imageReaders = ImageIO.getImageReaders(imageInputStream);
if (imageReaders.hasNext()) {
ImageReader imageReader = imageReaders.next();
try {
file.putUserData(FORMAT_KEY, imageReader.getFormatName());
ImageReadParam param = imageReader.getDefaultReadParam();
imageReader.setInput(imageInputStream, true, true);
int minIndex = imageReader.getMinIndex();
BufferedImage image = imageReader.read(minIndex, param);
file.putUserData(BUFFERED_IMAGE_REF_KEY, new SoftReference<BufferedImage>(image));
return true;
} finally {
imageReader.dispose();
}
}
} finally {
imageInputStream.close();
}
} finally {
// We perform loading no more needed
file.putUserData(TIMESTAMP_KEY, file.getTimeStamp());
}
}
return false;
}
@Nullable
public static BufferedImage getImage(@NotNull VirtualFile file) throws IOException {
refresh(file);
SoftReference<BufferedImage> imageRef = file.getUserData(BUFFERED_IMAGE_REF_KEY);
return SoftReference.dereference(imageRef);
}
@Nullable
public static String getFormat(@NotNull VirtualFile file) throws IOException {
refresh(file);
return file.getUserData(FORMAT_KEY);
}
public static String getReferencePath(Project project, VirtualFile file) {
final LogicalRoot logicalRoot = LogicalRootsManager.getLogicalRootsManager(project).findLogicalRoot(file);
if (logicalRoot != null) {
return getRelativePath(file, logicalRoot.getVirtualFile());
}
ProjectFileIndex fileIndex = ProjectRootManager.getInstance(project).getFileIndex();
VirtualFile sourceRoot = fileIndex.getSourceRootForFile(file);
if (sourceRoot != null) {
return getRelativePath(file, sourceRoot);
}
VirtualFile root = fileIndex.getContentRootForFile(file);
if (root != null) {
return getRelativePath(file, root);
}
return file.getPath();
}
private static String getRelativePath(final VirtualFile file, final VirtualFile root) {
if (root.equals(file)) {
return file.getPath();
}
return "/" + VfsUtilCore.getRelativePath(file, root, '/');
}
}