| /******************************************************************************* |
| * Copyright (c) 2009, 2017 xored software, Inc. |
| * This program and the accompanying materials are made available under the |
| * terms of the Eclipse Public License v. 2.0 which is available at |
| * http://www.eclipse.org/legal/epl-2.0. |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| *******************************************************************************/ |
| package org.eclipse.dltk.core.caching; |
| |
| import java.io.BufferedInputStream; |
| import java.io.File; |
| import java.io.IOException; |
| import java.util.ArrayList; |
| import java.util.List; |
| import java.util.zip.ZipEntry; |
| import java.util.zip.ZipFile; |
| |
| import org.eclipse.core.filesystem.EFS; |
| import org.eclipse.core.filesystem.IFileInfo; |
| import org.eclipse.core.filesystem.IFileStore; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.NullProgressMonitor; |
| import org.eclipse.core.runtime.Path; |
| import org.eclipse.dltk.core.DLTKContentTypeManager; |
| import org.eclipse.dltk.core.IDLTKLanguageToolkit; |
| import org.eclipse.dltk.core.caching.cache.CacheEntry; |
| import org.eclipse.dltk.core.caching.cache.CacheIndex; |
| import org.eclipse.emf.common.util.EList; |
| import org.eclipse.emf.common.util.URI; |
| import org.eclipse.emf.ecore.EObject; |
| import org.eclipse.emf.ecore.resource.Resource; |
| import org.eclipse.emf.ecore.xmi.impl.XMIResourceImpl; |
| |
| public class ArchiveIndexContentChecker { |
| private ZipFile zipFile; |
| private EList<EObject> contents; |
| private File file; |
| private long version; |
| private IDLTKLanguageToolkit toolkit; |
| |
| public ArchiveIndexContentChecker(File file, long version, |
| IDLTKLanguageToolkit toolkit) { |
| this.file = file; |
| this.version = version; |
| this.toolkit = toolkit; |
| try { |
| zipFile = new ZipFile(file); |
| |
| ZipEntry entry = zipFile.getEntry(".index"); |
| Resource indexResource = new XMIResourceImpl( |
| URI.createURI("dltk_cache://zipIndex")); |
| indexResource.load(new BufferedInputStream( |
| zipFile.getInputStream(entry), 8096), null); |
| contents = indexResource.getContents(); |
| } catch (Exception e) { |
| } |
| } |
| |
| public boolean containChanges() { |
| if (contents == null) { |
| return true; |
| } |
| File parent = file.getParentFile(); |
| List<File> collected = new ArrayList<>(); |
| for (EObject eObject : contents) { |
| CacheIndex cacheIndex = (CacheIndex) eObject; |
| EList<CacheEntry> entries = cacheIndex.getEntries(); |
| for (CacheEntry cacheEntry : entries) { |
| String path = cacheEntry.getPath(); |
| File childFile = new File(parent, path); |
| if (!childFile.exists()) { |
| return true; |
| } |
| if (cacheEntry.getLastAccessTime() != version) { |
| return true; |
| } |
| long timestamp = childFile.lastModified(); |
| try { |
| File canonicalFile = childFile.getCanonicalFile(); |
| if (!canonicalFile.getAbsolutePath() |
| .equals(file.getAbsolutePath())) { |
| // This is symlink |
| timestamp = canonicalFile.lastModified(); |
| } |
| } catch (IOException e) { |
| return true; |
| } |
| |
| long cacheStamp = cacheEntry.getTimestamp() / 1000; |
| timestamp = timestamp / 1000; |
| if (cacheStamp != timestamp) { |
| return true; |
| } |
| collected.add(childFile); |
| } |
| } |
| File[] listFiles = parent.listFiles(); |
| for (File file : listFiles) { |
| if (file.isFile() && needIndexing(file.getName()) |
| && !collected.contains(file)) { |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| /** |
| * @since 2.0 |
| */ |
| public boolean containChanges(IFileStore store) { |
| if (contents == null) { |
| return true; |
| } |
| IFileStore parent = store.getParent(); |
| List<IFileStore> collected = new ArrayList<>(); |
| for (EObject eObject : contents) { |
| CacheIndex cacheIndex = (CacheIndex) eObject; |
| EList<CacheEntry> entries = cacheIndex.getEntries(); |
| for (CacheEntry cacheEntry : entries) { |
| String path = cacheEntry.getPath(); |
| IFileStore childFile = parent.getChild(path); |
| IFileInfo childFileInfo = childFile.fetchInfo(); |
| if (!childFileInfo.exists()) { |
| return true; |
| } |
| if (cacheEntry.getLastAccessTime() != version) { |
| return true; |
| } |
| long timestamp = childFileInfo.getLastModified(); |
| if (childFileInfo.getAttribute(EFS.ATTRIBUTE_SYMLINK)) { |
| String canonicalFile = childFileInfo |
| .getStringAttribute(EFS.ATTRIBUTE_LINK_TARGET); |
| IFileStore fileStore = childFile |
| .getFileStore(new Path(canonicalFile)); |
| IFileInfo fetchInfo = fileStore.fetchInfo(); |
| timestamp = fetchInfo.getLastModified(); |
| } |
| long cacheStamp = cacheEntry.getTimestamp() / 1000; |
| timestamp = timestamp / 1000; |
| if (cacheStamp != timestamp) { |
| return true; |
| } |
| collected.add(childFile); |
| } |
| } |
| IFileStore[] listFiles = null; |
| try { |
| listFiles = parent.childStores(EFS.NONE, new NullProgressMonitor()); |
| } catch (CoreException e) { |
| e.printStackTrace(); |
| } |
| if (listFiles != null) { |
| for (IFileStore file : listFiles) { |
| IFileInfo fileInfo = file.fetchInfo(); |
| if (!fileInfo.isDirectory() && needIndexing(file.getName()) |
| && !collected.contains(file)) { |
| return true; |
| } |
| } |
| } |
| return false; |
| } |
| |
| private boolean needIndexing(String name) { |
| return DLTKContentTypeManager.isValidFileNameForContentType(toolkit, |
| new Path(name)); |
| } |
| } |