diff options
author | Eduard Bartsch | 2014-02-17 21:41:12 +0000 |
---|---|---|
committer | Eduard Bartsch | 2014-02-17 22:12:53 +0000 |
commit | 2c44c864e20184be40c82b39d2c1fac8a7508d2d (patch) | |
tree | 6d0fc1fc81b2dc79462fa6f98bac292778fceb0f | |
parent | ce3697763fef998b1c144b45155daf6c7676f181 (diff) | |
download | org.eclipse.e4.resources-2c44c864e20184be40c82b39d2c1fac8a7508d2d.tar.gz org.eclipse.e4.resources-2c44c864e20184be40c82b39d2c1fac8a7508d2d.tar.xz org.eclipse.e4.resources-2c44c864e20184be40c82b39d2c1fac8a7508d2d.zip |
[sfs] Improve SFS performance by splitting SFS metadata intoI20140807-2200I20140806-2200I20140806-0900I20140805-2200I20140804-2200I20140803-2200I20140802-2200I20140801-2200I20140731-2200I20140730-2200I20140730-0900I20140729-2200I20140728-2200I20140727-2200I20140726-2200I20140725-2200I20140724-2222I20140723-2200I20140723-0900I20140722-2200I20140721-2200I20140720-2200I20140719-2200I20140718-2200I20140717-2200I20140716-2200I20140716-0900I20140715-2200I20140714-2200I20140713-2200I20140712-2200I20140711-2200I20140710-2200I20140709-2200I20140709-0900I20140708-2200I20140707-2200I20140706-2200I20140705-2200I20140704-2200I20140703-2200I20140702-2200I20140702-0900I20140701-2200I20140630-2200I20140629-2200I20140628-2200I20140627-2200I20140626-2200I20140625-2200I20140625-0900I20140624-2200I20140623-2200I20140622-2200I20140621-2200I20140620-2200I20140619-2200I20140618-2200I20140618-0900I20140617-2200I20140616-2200I20140615-2200I20140614-2200I20140613-2200I20140612-2200I20140611-2200I20140611-0900I20140610-2200I20140609-2200I20140608-2200I20140607-2200I20140606-2200I20140606-0615I20140605-2200I20140604-2200I20140603-2200I20140602-2200I20140601-2200I20140531-2200I20140530-2200I20140530-0615I20140529-2200I20140528-2200I20140527-2200I20140526-2200I20140525-2200I20140524-2200I20140523-2200I20140523-0615I20140522-2200I20140521-2200I20140520-2200I20140519-2200I20140518-2200I20140517-2200I20140516-2200I20140516-0615I20140515-2200I20140514-2200I20140513-2200I20140512-2200I20140511-2200I20140510-2200I20140509-2200I20140509-0615I20140508-2200I20140507-2200I20140506-2200I20140505-2200I20140504-2200I20140503-2200I20140502-2200I20140502-0615I20140501-2200I20140430-2200I20140429-2200I20140428-2200I20140427-2200I20140426-2200I20140425-2200I20140425-0615I20140424-2200I20140423-2200I20140422-2200I20140421-2200I20140420-2200I20140419-2200I20140418-2200I20140418-0615I20140417-2200I20140416-2200I20140415-2200I20140414-2200I20140413-2200I20140412-2200I20140411-2200I20140411-0615I20140410-2200I20140409-2200I20140408-2200I20140407-2200I20140406-2200I20140405-2200I20140404-2200I20140404-0615I20140403-2200I20140402-2200
multiple files
Change-Id: I848956831a887770018c156b024a05e407c41904
24 files changed, 891 insertions, 225 deletions
diff --git a/bundles/org.eclipse.core.resources.semantic/META-INF/MANIFEST.MF b/bundles/org.eclipse.core.resources.semantic/META-INF/MANIFEST.MF index 8d6537a..56c81ba 100644 --- a/bundles/org.eclipse.core.resources.semantic/META-INF/MANIFEST.MF +++ b/bundles/org.eclipse.core.resources.semantic/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %Bundle-Name Bundle-SymbolicName: org.eclipse.core.resources.semantic;singleton:=true -Bundle-Version: 0.6.2.qualifier +Bundle-Version: 0.6.3.qualifier Bundle-Activator: org.eclipse.core.internal.resources.semantic.SemanticResourcesPlugin Require-Bundle: org.eclipse.core.runtime;bundle-version="3.4.0", org.eclipse.core.resources;bundle-version="3.4.2", @@ -15,7 +15,7 @@ Bundle-RequiredExecutionEnvironment: J2SE-1.5 Bundle-Localization: plugin Export-Package: org.eclipse.core.internal.resources.semantic;x-friends:="org.eclipse.core.resources.semantic.test,org.eclipse.ui.resources.semantic", org.eclipse.core.internal.resources.semantic.cacheservice;x-friends:="org.eclipse.core.resources.semantic.test", - org.eclipse.core.internal.resources.semantic.model.SemanticResourceDB;x-internal:=true, + org.eclipse.core.internal.resources.semantic.model.SemanticResourceDB;x-friends:="org.eclipse.core.resources.semantic.test", org.eclipse.core.internal.resources.semantic.model.SemanticResourceDB.impl;x-internal:=true, org.eclipse.core.internal.resources.semantic.model.SemanticResourceDB.util;x-internal:=true, org.eclipse.core.internal.resources.semantic.provider;x-friends:="org.eclipse.core.resources.semantic.test,,org.eclipse.ui.resources.semantic.examples", diff --git a/bundles/org.eclipse.core.resources.semantic/SemanticDB.genmodel b/bundles/org.eclipse.core.resources.semantic/SemanticDB.genmodel index 59c2613..c3d0363 100644 --- a/bundles/org.eclipse.core.resources.semantic/SemanticDB.genmodel +++ b/bundles/org.eclipse.core.resources.semantic/SemanticDB.genmodel @@ -1,10 +1,9 @@ <?xml version="1.0" encoding="UTF-8"?> -<genmodel:GenModel xmi:version="2.0" - xmlns:xmi="http://www.omg.org/XMI" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" - xmlns:genmodel="http://www.eclipse.org/emf/2002/GenModel" copyrightText="" - modelDirectory="org.eclipse.core.resources.semantic/src" modelPluginID="org.eclipse.core.resources.semantic" - modelName="SemanticDB" nonNLSMarkers="true" importerID="org.eclipse.emf.importer.ecore" - complianceLevel="6.0" copyrightFields="false" language="" classNamePattern=""> +<genmodel:GenModel xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" + xmlns:genmodel="http://www.eclipse.org/emf/2002/GenModel" copyrightText="" modelDirectory="org.eclipse.core.resources.semantic/src" + modelPluginID="org.eclipse.core.resources.semantic" modelName="SemanticDB" nonNLSMarkers="true" + importerID="org.eclipse.emf.importer.ecore" containmentProxies="true" complianceLevel="6.0" + copyrightFields="false" language="" classNamePattern=""> <foreignModel>SemanticDB.ecore</foreignModel> <genPackages prefix="SemanticResourceDB" basePackage="org.eclipse.core.internal.resources.semantic.model" disposableProviderFactory="true" fileExtensions="" ecorePackage="SemanticDB.ecore#/"> @@ -27,6 +26,9 @@ <genFeatures createChild="false" ecoreFeature="ecore:EAttribute SemanticDB.ecore#//ResourceTreeNode/type"/> <genFeatures createChild="false" ecoreFeature="ecore:EAttribute SemanticDB.ecore#//ResourceTreeNode/sessionProperties"/> <genFeatures createChild="false" ecoreFeature="ecore:EAttribute SemanticDB.ecore#//ResourceTreeNode/path"/> + <genFeatures createChild="false" ecoreFeature="ecore:EAttribute SemanticDB.ecore#//ResourceTreeNode/queryPart"/> + <genFeatures createChild="false" ecoreFeature="ecore:EAttribute SemanticDB.ecore#//ResourceTreeNode/remoteURI"/> + <genFeatures createChild="false" ecoreFeature="ecore:EAttribute SemanticDB.ecore#//ResourceTreeNode/dynamicContentProviderID"/> </genClasses> <genClasses ecoreClass="SemanticDB.ecore#//SemanticDB"> <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference SemanticDB.ecore#//SemanticDB/roots"/> diff --git a/bundles/org.eclipse.core.resources.semantic/plugin.properties b/bundles/org.eclipse.core.resources.semantic/plugin.properties index d6d4e01..c0ceacc 100644 --- a/bundles/org.eclipse.core.resources.semantic/plugin.properties +++ b/bundles/org.eclipse.core.resources.semantic/plugin.properties @@ -18,4 +18,6 @@ wizard.name.SyncConfig = Semantic File System extension-point.name = Semantic Folder Template historyPageProviderExtPoint_XGRP = Semantic File System History Page contentProviderExtPoint_XGRP = Semantic File System Content Provider -pathMappingExtPoint_XGRP = Path to Semantic File System Content Provider Mapping
\ No newline at end of file +pathMappingExtPoint_XGRP = Path to Semantic File System Content Provider Mapping +pluginName = Semantic File System Implementation +providerName = www.eclipse.org diff --git a/bundles/org.eclipse.core.resources.semantic/pom.xml b/bundles/org.eclipse.core.resources.semantic/pom.xml index 53f9fbf..8dbe53d 100644 --- a/bundles/org.eclipse.core.resources.semantic/pom.xml +++ b/bundles/org.eclipse.core.resources.semantic/pom.xml @@ -9,7 +9,7 @@ <groupId>org.eclipse.e4</groupId> <artifactId>org.eclipse.core.resources.semantic</artifactId> - <version>0.6.2-SNAPSHOT</version> + <version>0.6.3-SNAPSHOT</version> <packaging>eclipse-plugin</packaging> </project> diff --git a/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/SemanticFileStore.java b/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/SemanticFileStore.java index b632b32..1148415 100644 --- a/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/SemanticFileStore.java +++ b/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/SemanticFileStore.java @@ -710,7 +710,7 @@ public class SemanticFileStore extends SemanticProperties implements ISemanticFi this.fs.switchToExists(this.node, this.fs.getParentNode(this.node)); this.node.setType(TreeNodeType.FILE); try { - this.fs.requestFlush(false); + this.fs.requestFlush(false, this.node); } catch (CoreException e) { Util.safeClose(os); throw e; @@ -836,8 +836,13 @@ public class SemanticFileStore extends SemanticProperties implements ISemanticFi checkAccessible(); ((SemanticFileStore) targetParent).checkAccessible(); + ResourceTreeNode currentParent = this.node.getParent(); + this.node.setParent(((SemanticFileStore) targetParent).node); this.node.setName(targetName); + + this.fs.requestFlush(true, currentParent); + this.fs.requestFlush(true, ((SemanticFileStore) targetParent).node); } finally { this.fs.unlockForWrite(); } @@ -1399,7 +1404,7 @@ public class SemanticFileStore extends SemanticProperties implements ISemanticFi createChildNode(name, true, null); - this.fs.requestFlush(false); + this.fs.requestFlush(false, this.node); } finally { this.fs.unlockForWrite(); } @@ -1444,7 +1449,7 @@ public class SemanticFileStore extends SemanticProperties implements ISemanticFi // we don't use an empty map, but null child.setPersistentProperties(null); } - this.fs.requestFlush(false); + this.fs.requestFlush(false, this.node); } finally { this.fs.unlockForWrite(); @@ -1477,7 +1482,7 @@ public class SemanticFileStore extends SemanticProperties implements ISemanticFi createChildNode(name, false, null); - this.fs.requestFlush(false); + this.fs.requestFlush(false, this.node); } finally { this.fs.unlockForWrite(); } @@ -1504,7 +1509,7 @@ public class SemanticFileStore extends SemanticProperties implements ISemanticFi createLocalChildNode(name, this.getPath().append(name), contentProviderID); - this.fs.requestFlush(false); + this.fs.requestFlush(false, this.node); } finally { this.fs.unlockForWrite(); } @@ -1864,13 +1869,15 @@ public class SemanticFileStore extends SemanticProperties implements ISemanticFi SemanticFileStore.cleanupNodeAndChildren(node, getPath()); + ResourceTreeNode topParent = this.fs.getHighestParent(this.node); + if (this.node instanceof TreeRoot) { ((TreeRoot) this.node).setParentDB(null); } else { this.node.setParent(null); } - this.fs.requestFlush(false); + this.fs.requestFlush(false, topParent); this.fs.requestURILocatorRebuild(); } finally { diff --git a/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/SemanticFileSystem.java b/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/SemanticFileSystem.java index b9af0e2..c2b97d9 100644 --- a/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/SemanticFileSystem.java +++ b/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/SemanticFileSystem.java @@ -25,9 +25,7 @@ import org.eclipse.core.filesystem.EFS; import org.eclipse.core.filesystem.IFileStore; import org.eclipse.core.filesystem.provider.FileSystem; import org.eclipse.core.internal.resources.semantic.model.SemanticResourceDB.ResourceTreeNode; -import org.eclipse.core.internal.resources.semantic.model.SemanticResourceDB.SemanticDB; import org.eclipse.core.internal.resources.semantic.model.SemanticResourceDB.SemanticResourceDBFactory; -import org.eclipse.core.internal.resources.semantic.model.SemanticResourceDB.SemanticResourceDBPackage; import org.eclipse.core.internal.resources.semantic.model.SemanticResourceDB.TreeNodeType; import org.eclipse.core.internal.resources.semantic.model.SemanticResourceDB.TreeRoot; import org.eclipse.core.internal.resources.semantic.util.ISemanticFileSystemLog; @@ -46,11 +44,7 @@ import org.eclipse.core.runtime.Path; import org.eclipse.emf.common.util.EList; import org.eclipse.emf.common.util.TreeIterator; import org.eclipse.emf.ecore.EObject; -import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.ecore.resource.Resource.Diagnostic; -import org.eclipse.emf.ecore.resource.ResourceSet; -import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl; -import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl; /** * The Semantic File System. @@ -69,11 +63,10 @@ public class SemanticFileSystem extends FileSystem implements ISemanticFileSyste private final Lock writeLock = this.rwl.writeLock(); private final ISemanticFileSystemLog log; - private SemanticDB db; - Resource metadataResource; + SemanticMetadataPersistenceManager mgr; + private File metadataFolder; + private SemanticURILocatorService uriLocator; - private boolean isDelayedFlush = false; - private boolean needsFlush = false; /** * No-argument constructor @@ -82,12 +75,19 @@ public class SemanticFileSystem extends FileSystem implements ISemanticFileSyste this.log = new SemanticFileSystemLog(); - init(); + init(null); + } + + public SemanticFileSystem(File rootFolder) { + + this.log = new SemanticFileSystemLog(); + + init(rootFolder); } public String[] getRootNames() throws CoreException { - if (this.db == null) { + if (this.mgr.getSemanticDB() == null) { throw new SemanticResourceException(SemanticResourceStatusCode.SFS_DB_NOT_INITIALIZED, SemanticFileSystem.EMPTY, Messages.SemanticFileSystem_NotInitialized_XMSG); } @@ -97,7 +97,7 @@ public class SemanticFileSystem extends FileSystem implements ISemanticFileSyste try { lockForRead(); - EList<TreeRoot> roots = this.db.getRoots(); + EList<TreeRoot> roots = this.mgr.getSemanticDB().getRoots(); for (TreeRoot treeRoot : roots) { result.add(treeRoot.getName()); @@ -116,12 +116,19 @@ public class SemanticFileSystem extends FileSystem implements ISemanticFileSyste * @throws CoreException * in case of failure */ - public void requestFlush(boolean force) throws CoreException { - this.needsFlush = true; + public void requestFlush(boolean force, ResourceTreeNode node) throws CoreException { + node = getHighestParent(node); + + saveSemanticDB(node.getName()); + } - if (!this.isDelayedFlush || force) { - saveSemanticDB(); + public ResourceTreeNode getHighestParent(ResourceTreeNode node) { + ResourceTreeNode parent = node.getParent(); + while (parent != null) { + node = parent; + parent = node.getParent(); } + return node; } @Override @@ -141,7 +148,7 @@ public class SemanticFileSystem extends FileSystem implements ISemanticFileSyste path = Path.EMPTY; } - if (this.db == null) { + if (this.mgr.getSemanticDB() == null) { return EFS.getNullFileSystem().getStore(path); } @@ -151,7 +158,7 @@ public class SemanticFileSystem extends FileSystem implements ISemanticFileSyste try { lockForWrite(); - EList<TreeRoot> roots = this.db.getRoots(); + EList<TreeRoot> roots = this.mgr.getSemanticDB().getRoots(); TreeRoot treeRoot = null; @@ -284,8 +291,8 @@ public class SemanticFileSystem extends FileSystem implements ISemanticFileSyste try { lockForRead(); - if (this.db != null) { - EList<TreeRoot> roots = this.db.getRoots(); + if (this.mgr.getSemanticDB() != null) { + EList<TreeRoot> roots = this.mgr.getSemanticDB().getRoots(); for (TreeRoot treeRoot : roots) { if (path.segment(0).equals(treeRoot.getName())) { @@ -349,8 +356,8 @@ public class SemanticFileSystem extends FileSystem implements ISemanticFileSyste try { lockForRead(); - if (this.db != null) { - EList<TreeRoot> roots = this.db.getRoots(); + if (this.mgr.getSemanticDB() != null) { + EList<TreeRoot> roots = this.mgr.getSemanticDB().getRoots(); for (TreeRoot treeRoot : roots) { if (path.segment(0).equals(treeRoot.getName())) { @@ -462,7 +469,7 @@ public class SemanticFileSystem extends FileSystem implements ISemanticFileSyste void switchToExists(ResourceTreeNode node, ResourceTreeNode parent) { if (!node.isExists()) { if (node instanceof TreeRoot) { - ((TreeRoot) node).setParentDB(this.db); + ((TreeRoot) node).setParentDB(this.mgr.getSemanticDB()); } else { if (parent != null) { @@ -517,59 +524,19 @@ public class SemanticFileSystem extends FileSystem implements ISemanticFileSyste return new SemanticFileStore(this, node); } - private void init() { - - File metadataFolder = SemanticResourcesPlugin.getCacheLocation().toFile(); - metadataFolder.mkdirs(); - - File metadataFile = new File(metadataFolder, SemanticFileSystem.METADATA_FILENAME); - - String metadataLocation = metadataFile.getAbsolutePath(); - - if (!metadataFile.exists()) { - initSemanticDB(metadataLocation); - + private void init(File rootFolder) { + if (rootFolder != null) { + this.metadataFolder = rootFolder; } else { - loadSemanticDB(metadataLocation); + this.metadataFolder = SemanticResourcesPlugin.getCacheLocation().toFile(); } - } - private void loadSemanticDB(String metadataLocation) { - try { - SemanticResourceDBPackage pkg = SemanticResourceDBPackage.eINSTANCE; - pkg.eClass(); + mgr = new SemanticMetadataPersistenceManager(metadataFolder); - try { - this.lockForWrite(); - - ResourceSet resourceset = new ResourceSetImpl(); - - org.eclipse.emf.common.util.URI uri = org.eclipse.emf.common.util.URI.createFileURI(metadataLocation); - - // Register the appropriate resource factory to handle all file - // extensions that would cover XMI as well. - resourceset.getResourceFactoryRegistry().getExtensionToFactoryMap().put(Resource.Factory.Registry.DEFAULT_EXTENSION, - new XMIResourceFactoryImpl()); - - this.metadataResource = resourceset.createResource(uri); - - this.metadataResource.load(null); - - EList<EObject> contents = this.metadataResource.getContents(); - - for (EObject eObject : contents) { - if (eObject instanceof SemanticDB) { - this.db = (SemanticDB) eObject; - this.migrateSemanticDB(); - break; - } - } - } finally { - this.unlockForWrite(); - } - this.needsFlush = false; + try { + mgr.init(); } catch (IOException e) { - for (Diagnostic diagnostic : this.metadataResource.getErrors()) { + for (Diagnostic diagnostic : mgr.getMetadataResource().getErrors()) { this.log.log(new SemanticResourceException(SemanticResourceStatusCode.SFS_INITIALIZATION_ERROR, SemanticFileSystem.EMPTY, diagnostic.getMessage())); } @@ -579,62 +546,6 @@ public class SemanticFileSystem extends FileSystem implements ISemanticFileSyste } } - private void migrateSemanticDB() { - TreeIterator<EObject> objects = this.db.eAllContents(); - ArrayList<ResourceTreeNode> toBeRemoved = new ArrayList<ResourceTreeNode>(); - - try { - while (objects.hasNext()) { - EObject eObject = objects.next(); - if (eObject instanceof TreeRoot) { - TreeRoot root = (TreeRoot) eObject; - - if (!root.isExists()) { - toBeRemoved.add(root); - } - } else if (eObject instanceof ResourceTreeNode) { - ResourceTreeNode node = (ResourceTreeNode) eObject; - - if (!node.isExists()) { - toBeRemoved.add(node); - } - } - } - - for (ResourceTreeNode resourceTreeNode : toBeRemoved) { - if (resourceTreeNode instanceof TreeRoot) { - ((TreeRoot) resourceTreeNode).setParentDB(null); - } else { - resourceTreeNode.setParent(null); - } - } - } catch (Throwable e) { - this.db = null; - this.log.log(new SemanticResourceException(SemanticResourceStatusCode.SFS_INITIALIZATION_ERROR, SemanticFileSystem.EMPTY, - Messages.SemanticFileSystem_SFSInitError_XMSG, e)); - } - - } - - private void initSemanticDB(String metadataLocation) { - try { - this.lockForWrite(); - ResourceSet resourceset = new ResourceSetImpl(); - - org.eclipse.emf.common.util.URI uri = org.eclipse.emf.common.util.URI.createFileURI(metadataLocation); - - this.metadataResource = resourceset.createResource(uri); - - this.db = SemanticResourceDBFactory.eINSTANCE.createSemanticDB(); - - this.metadataResource.getContents().add(this.db); - - this.needsFlush = true; - } finally { - this.unlockForWrite(); - } - } - private TreeRoot createRootNode(String name) { TreeRoot root = SemanticResourceDBFactory.eINSTANCE.createTreeRoot(); @@ -664,7 +575,7 @@ public class SemanticFileSystem extends FileSystem implements ISemanticFileSyste if (parser.getShouldCreate()) { root.setExists(true); root.setPath(null); - root.setParentDB(this.db); + root.setParentDB(this.mgr.getSemanticDB()); } } return root; @@ -676,19 +587,17 @@ public class SemanticFileSystem extends FileSystem implements ISemanticFileSyste node.setRemoteURI(parser.getURI()); } - private void saveSemanticDB() throws CoreException { + private void saveSemanticDB(String name) throws CoreException { try { - if (this.needsFlush) { - if (SfsTraceLocation.CORE_DB.isActive()) { - SfsTraceLocation.getTrace().traceEntry(SfsTraceLocation.CORE_DB.getLocation()); - } - try { - this.lockForWrite(); - this.metadataResource.save(null); - this.needsFlush = false; - } finally { - this.unlockForWrite(); - } + if (SfsTraceLocation.CORE_DB.isActive()) { + SfsTraceLocation.getTrace().traceEntry(SfsTraceLocation.CORE_DB.getLocation()); + } + try { + this.lockForWrite(); + + this.mgr.saveSemanticDB(name); + } finally { + this.unlockForWrite(); } } catch (IOException e) { SemanticResourceException ex = new SemanticResourceException(SemanticResourceStatusCode.SFS_ERROR_WRITING_METADATA, @@ -715,10 +624,6 @@ public class SemanticFileSystem extends FileSystem implements ISemanticFileSyste } public String getPathToDb() { - - File metadataFolder = SemanticResourcesPlugin.getCacheLocation().toFile(); - metadataFolder.mkdirs(); - File metadataFile = new File(metadataFolder, SemanticFileSystem.METADATA_FILENAME); String metadataLocation = metadataFile.getAbsolutePath(); @@ -800,7 +705,7 @@ public class SemanticFileSystem extends FileSystem implements ISemanticFileSyste public void rebuildMapping(IProgressMonitor monitor) { this.uri2pathMapping.clear(); - TreeIterator<EObject> contents = this.fs.metadataResource.getAllContents(); + TreeIterator<EObject> contents = this.fs.mgr.getMetadataResource().getAllContents(); while (contents.hasNext()) { EObject eObject = contents.next(); diff --git a/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/SemanticMetadataPersistenceManager.java b/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/SemanticMetadataPersistenceManager.java new file mode 100644 index 0000000..7232043 --- /dev/null +++ b/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/SemanticMetadataPersistenceManager.java @@ -0,0 +1,241 @@ +/******************************************************************************* + * Copyright (c) 2013 SAP AG. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Eduard Bartsch (SAP AG) - initial API and implementation + *******************************************************************************/ +package org.eclipse.core.internal.resources.semantic; + +import java.io.File; +import java.io.FilenameFilter; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import org.eclipse.core.internal.resources.semantic.model.SemanticResourceDB.ResourceTreeNode; +import org.eclipse.core.internal.resources.semantic.model.SemanticResourceDB.SemanticDB; +import org.eclipse.core.internal.resources.semantic.model.SemanticResourceDB.SemanticResourceDBFactory; +import org.eclipse.core.internal.resources.semantic.model.SemanticResourceDB.SemanticResourceDBPackage; +import org.eclipse.core.internal.resources.semantic.model.SemanticResourceDB.TreeRoot; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.common.util.TreeIterator; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.ecore.resource.ResourceSet; +import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl; +import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl; + +public class SemanticMetadataPersistenceManager { + + private static final String METADATA_FILENAME = "metadata.xmi"; //$NON-NLS-1$ + final static IPath EMPTY = new Path(""); //$NON-NLS-1$ + + private SemanticDB db; + + private Map<String, Resource> metadataResourceMap = new HashMap<String, Resource>(); + private File metadataFolder; + Resource metadataResource; + ResourceSet metadataResourceSet = new ResourceSetImpl(); + + public SemanticMetadataPersistenceManager(File metadataFolder) { + this.metadataFolder = metadataFolder; + } + + public SemanticDB getSemanticDB() { + return db; + } + + public String getMetadataResourceLocation(String name) { + return getMetadataFile(name).getAbsolutePath(); + } + + public String getMetadataFileName(String name) { + return "$." + name + ".xmi"; //$NON-NLS-1$ //$NON-NLS-2$ + } + + public void init() throws IOException { + // Register the appropriate resource factory to handle all file + // extensions that would cover XMI as well. + metadataResourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap() + .put(Resource.Factory.Registry.DEFAULT_EXTENSION, new XMIResourceFactoryImpl()); + + metadataFolder.mkdirs(); + + File metadataFile = getMetadataFile(null); + + if (!metadataFile.exists()) { + initSemanticDB(); + } else { + loadSemanticDB(); + } + } + + public void initSemanticDB() { + this.metadataResource = metadataResourceSet.createResource(getResourceURI(METADATA_FILENAME)); + + this.db = SemanticResourceDBFactory.eINSTANCE.createSemanticDB(); + + this.metadataResource.getContents().add(this.db); + } + + private void loadSemanticDB() throws IOException { + SemanticResourceDBPackage pkg = SemanticResourceDBPackage.eINSTANCE; + pkg.eClass(); + + this.metadataResource = metadataResourceSet.createResource(getResourceURI(METADATA_FILENAME)); + + this.metadataResource.load(null); + + EList<EObject> contents = this.metadataResource.getContents(); + + for (EObject eObject : contents) { + if (eObject instanceof SemanticDB) { + this.db = (SemanticDB) eObject; + this.migrateSemanticDB(); + break; + } + } + } + + public void saveSemanticDB(String projectName) throws IOException { + if (SfsTraceLocation.CORE_DB.isActive()) { + SfsTraceLocation.getTrace().traceEntry(SfsTraceLocation.CORE_DB.getLocation()); + } + + // force assignment to separate resources + EList<TreeRoot> roots = this.db.getRoots(); + for (TreeRoot treeRoot : roots) { + if (projectName == null || projectName.equals(treeRoot.getName())) { + assignToProjectSpecificMetadataResource(treeRoot); + } + } + + this.metadataResource.save(null); + + if (projectName == null) { + for (Entry<String, Resource> resourceEntry : this.metadataResourceMap.entrySet()) { + resourceEntry.getValue().save(null); + } + } else { + Resource resource = this.metadataResourceMap.get(projectName); + + resource.save(null); + } + } + + public File getMetadataFile(String name) { + String fileName; + + if (name != null) { + fileName = getMetadataFileName(name); + } else { + fileName = METADATA_FILENAME; + } + + return new File(metadataFolder, fileName); + } + + public void migrateSemanticDB() throws IOException { + TreeIterator<EObject> objects = this.db.eAllContents(); + ArrayList<ResourceTreeNode> toBeRemoved = new ArrayList<ResourceTreeNode>(); + Set<String> filesToBeRemoved = listMetadataFiles(); + + while (objects.hasNext()) { + EObject eObject = objects.next(); + if (eObject instanceof TreeRoot) { + TreeRoot root = (TreeRoot) eObject; + + if (!root.isExists()) { + toBeRemoved.add(root); + } else { + assignToProjectSpecificMetadataResource(root); + filesToBeRemoved.remove(getMetadataFileName(root.getName())); + } + } else if (eObject instanceof ResourceTreeNode) { + ResourceTreeNode node = (ResourceTreeNode) eObject; + + if (!node.isExists()) { + toBeRemoved.add(node); + } + } + } + + for (ResourceTreeNode resourceTreeNode : toBeRemoved) { + if (resourceTreeNode instanceof TreeRoot) { + ((TreeRoot) resourceTreeNode).setParentDB(null); + this.db.getRoots().remove(resourceTreeNode); + } else { + resourceTreeNode.setParent(null); + } + } + + for (String fileName : filesToBeRemoved) { + File file = new File(this.metadataFolder, fileName); + if (file.exists()) { + file.delete(); + } + } + + this.metadataResource.save(null); + + for (String name : this.metadataResourceMap.keySet()) { + File file = getMetadataFile(name); + + if (!file.exists()) { + Resource resource = this.metadataResourceMap.get(name); + + resource.save(null); + } + } + } + + private Set<String> listMetadataFiles() { + File[] files = this.metadataFolder.listFiles(new FilenameFilter() { + public boolean accept(File dir, String name) { + return name.endsWith(".xmi") && !name.equals(METADATA_FILENAME); //$NON-NLS-1$ + } + }); + + Set<String> names = new HashSet<String>(); + for (File file : files) { + names.add(file.getName()); + } + return names; + } + + private void assignToProjectSpecificMetadataResource(TreeRoot root) { + Resource resource = this.metadataResourceMap.get(root.getName()); + + if (resource == null) { + org.eclipse.emf.common.util.URI uri = org.eclipse.emf.common.util.URI + .createFileURI(getMetadataResourceLocation(root.getName())); + resource = this.metadataResourceSet.createResource(uri); + this.metadataResourceMap.put(root.getName(), resource); + } + + resource.getContents().add(root); + } + + private org.eclipse.emf.common.util.URI getResourceURI(String fileName) { + File metadataFile = new File(metadataFolder, fileName); + + String metadataLocation = metadataFile.getAbsolutePath(); + + return org.eclipse.emf.common.util.URI.createFileURI(metadataLocation); + } + + public Resource getMetadataResource() { + return this.metadataResource; + } + +} diff --git a/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/SemanticProperties.java b/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/SemanticProperties.java index fce7034..35cfa89 100644 --- a/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/SemanticProperties.java +++ b/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/SemanticProperties.java @@ -154,7 +154,7 @@ public abstract class SemanticProperties extends FileStore implements ISemanticP this.notifyPersistentPropertySet(keyString, oldValue, value); - this.fs.requestFlush(false); + this.fs.requestFlush(false, this.node); } } finally { this.fs.unlockForWrite(); @@ -216,7 +216,7 @@ public abstract class SemanticProperties extends FileStore implements ISemanticP if (needsFlush) { this.node.setPersistentProperties(map); - this.fs.requestFlush(false); + this.fs.requestFlush(false, node); } } finally { this.fs.unlockForWrite(); diff --git a/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/model/SemanticResourceDB/ResourceTreeNode.java b/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/model/SemanticResourceDB/ResourceTreeNode.java index eb2f622..9124a8f 100644 --- a/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/model/SemanticResourceDB/ResourceTreeNode.java +++ b/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/model/SemanticResourceDB/ResourceTreeNode.java @@ -119,7 +119,7 @@ public interface ResourceTreeNode extends EObject { * @return the value of the '<em>Children</em>' containment reference list. * @see org.eclipse.core.internal.resources.semantic.model.SemanticResourceDB.SemanticResourceDBPackage#getResourceTreeNode_Children() * @see org.eclipse.core.internal.resources.semantic.model.SemanticResourceDB.ResourceTreeNode#getParent - * @model opposite="parent" containment="true" + * @model opposite="parent" containment="true" resolveProxies="true" * @generated */ EList<ResourceTreeNode> getChildren(); @@ -229,7 +229,8 @@ public interface ResourceTreeNode extends EObject { * @return the value of the '<em>Persistent Properties</em>' attribute. * @see #setPersistentProperties(HashMap) * @see org.eclipse.core.internal.resources.semantic.model.SemanticResourceDB.SemanticResourceDBPackage#getResourceTreeNode_PersistentProperties() - * @model dataType="org.eclipse.core.internal.resources.semantic.model.SemanticResourceDB.PersistentProperties" + * @model dataType= + * "org.eclipse.core.internal.resources.semantic.model.SemanticResourceDB.PersistentProperties" * @generated */ HashMap<String, String> getPersistentProperties(); @@ -323,7 +324,8 @@ public interface ResourceTreeNode extends EObject { * @return the value of the '<em>Session Properties</em>' attribute. * @see #setSessionProperties(HashMap) * @see org.eclipse.core.internal.resources.semantic.model.SemanticResourceDB.SemanticResourceDBPackage#getResourceTreeNode_SessionProperties() - * @model dataType="org.eclipse.core.internal.resources.semantic.model.SemanticResourceDB.SessionProperties" + * @model dataType= + * "org.eclipse.core.internal.resources.semantic.model.SemanticResourceDB.SessionProperties" * transient="true" * @generated */ diff --git a/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/model/SemanticResourceDB/SemanticDB.java b/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/model/SemanticResourceDB/SemanticDB.java index 8227ef1..05ae0ea 100644 --- a/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/model/SemanticResourceDB/SemanticDB.java +++ b/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/model/SemanticResourceDB/SemanticDB.java @@ -51,7 +51,7 @@ public interface SemanticDB extends EObject { * @return the value of the '<em>Roots</em>' containment reference list. * @see org.eclipse.core.internal.resources.semantic.model.SemanticResourceDB.SemanticResourceDBPackage#getSemanticDB_Roots() * @see org.eclipse.core.internal.resources.semantic.model.SemanticResourceDB.TreeRoot#getParentDB - * @model opposite="parentDB" containment="true" + * @model opposite="parentDB" containment="true" resolveProxies="true" * @generated */ EList<TreeRoot> getRoots(); diff --git a/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/model/SemanticResourceDB/impl/ResourceTreeNodeImpl.java b/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/model/SemanticResourceDB/impl/ResourceTreeNodeImpl.java index 865947a..bcbbf64 100644 --- a/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/model/SemanticResourceDB/impl/ResourceTreeNodeImpl.java +++ b/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/model/SemanticResourceDB/impl/ResourceTreeNodeImpl.java @@ -345,7 +345,7 @@ public class ResourceTreeNodeImpl extends EObjectImpl implements ResourceTreeNod */ public EList<ResourceTreeNode> getChildren() { if (children == null) { - children = new EObjectContainmentWithInverseEList<ResourceTreeNode>(ResourceTreeNode.class, this, + children = new EObjectContainmentWithInverseEList.Resolving<ResourceTreeNode>(ResourceTreeNode.class, this, SemanticResourceDBPackage.RESOURCE_TREE_NODE__CHILDREN, SemanticResourceDBPackage.RESOURCE_TREE_NODE__PARENT); } return children; @@ -367,6 +367,17 @@ public class ResourceTreeNodeImpl extends EObjectImpl implements ResourceTreeNod * * @generated */ + public ResourceTreeNode basicGetParent() { + if (eContainerFeatureID() != SemanticResourceDBPackage.RESOURCE_TREE_NODE__PARENT) + return null; + return (ResourceTreeNode) eInternalContainer(); + } + + /** + * <!-- begin-user-doc --> <!-- end-user-doc --> + * + * @generated + */ public NotificationChain basicSetParent(ResourceTreeNode newParent, NotificationChain msgs) { msgs = eBasicSetContainer((InternalEObject) newParent, SemanticResourceDBPackage.RESOURCE_TREE_NODE__PARENT, msgs); return msgs; @@ -677,7 +688,9 @@ public class ResourceTreeNodeImpl extends EObjectImpl implements ResourceTreeNod case SemanticResourceDBPackage.RESOURCE_TREE_NODE__CHILDREN : return getChildren(); case SemanticResourceDBPackage.RESOURCE_TREE_NODE__PARENT : - return getParent(); + if (resolve) + return getParent(); + return basicGetParent(); case SemanticResourceDBPackage.RESOURCE_TREE_NODE__EXISTS : return isExists(); case SemanticResourceDBPackage.RESOURCE_TREE_NODE__TEMPLATE_ID : @@ -819,7 +832,7 @@ public class ResourceTreeNodeImpl extends EObjectImpl implements ResourceTreeNod case SemanticResourceDBPackage.RESOURCE_TREE_NODE__CHILDREN : return children != null && !children.isEmpty(); case SemanticResourceDBPackage.RESOURCE_TREE_NODE__PARENT : - return getParent() != null; + return basicGetParent() != null; case SemanticResourceDBPackage.RESOURCE_TREE_NODE__EXISTS : return exists != EXISTS_EDEFAULT; case SemanticResourceDBPackage.RESOURCE_TREE_NODE__TEMPLATE_ID : diff --git a/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/model/SemanticResourceDB/impl/SemanticDBImpl.java b/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/model/SemanticResourceDB/impl/SemanticDBImpl.java index 211106c..fe69588 100644 --- a/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/model/SemanticResourceDB/impl/SemanticDBImpl.java +++ b/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/model/SemanticResourceDB/impl/SemanticDBImpl.java @@ -79,8 +79,8 @@ public class SemanticDBImpl extends EObjectImpl implements SemanticDB { */ public EList<TreeRoot> getRoots() { if (roots == null) { - roots = new EObjectContainmentWithInverseEList<TreeRoot>(TreeRoot.class, this, SemanticResourceDBPackage.SEMANTIC_DB__ROOTS, - SemanticResourceDBPackage.TREE_ROOT__PARENT_DB); + roots = new EObjectContainmentWithInverseEList.Resolving<TreeRoot>(TreeRoot.class, this, + SemanticResourceDBPackage.SEMANTIC_DB__ROOTS, SemanticResourceDBPackage.TREE_ROOT__PARENT_DB); } return roots; } diff --git a/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/model/SemanticResourceDB/impl/SemanticResourceDBFactoryImpl.java b/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/model/SemanticResourceDB/impl/SemanticResourceDBFactoryImpl.java index e212379..dd4e1a6 100644 --- a/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/model/SemanticResourceDB/impl/SemanticResourceDBFactoryImpl.java +++ b/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/model/SemanticResourceDB/impl/SemanticResourceDBFactoryImpl.java @@ -22,6 +22,7 @@ import org.eclipse.core.internal.resources.semantic.model.SemanticResourceDB.Sem import org.eclipse.core.internal.resources.semantic.model.SemanticResourceDB.SemanticResourceDBPackage; import org.eclipse.core.internal.resources.semantic.model.SemanticResourceDB.TreeNodeType; import org.eclipse.core.internal.resources.semantic.model.SemanticResourceDB.TreeRoot; +import org.eclipse.core.runtime.QualifiedName; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EDataType; import org.eclipse.emf.ecore.EObject; @@ -180,8 +181,8 @@ public class SemanticResourceDBFactoryImpl extends EFactoryImpl implements Seman * @generated */ @SuppressWarnings("rawtypes") - public HashMap createPersistentPropertiesFromString(EDataType eDataType, String initialValue) { - return (HashMap) super.createFromString(initialValue); + public HashMap<String, String> createPersistentPropertiesFromString(EDataType eDataType, String initialValue) { + return (HashMap<String, String>) super.createFromString(initialValue); } /** @@ -199,8 +200,8 @@ public class SemanticResourceDBFactoryImpl extends EFactoryImpl implements Seman * @generated */ @SuppressWarnings("rawtypes") - public HashMap createSessionPropertiesFromString(EDataType eDataType, String initialValue) { - return (HashMap) super.createFromString(initialValue); + public HashMap<QualifiedName, Object> createSessionPropertiesFromString(EDataType eDataType, String initialValue) { + return (HashMap<QualifiedName, Object>) super.createFromString(initialValue); } /** diff --git a/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/model/SemanticResourceDB/impl/SemanticResourceDBPackageImpl.java b/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/model/SemanticResourceDB/impl/SemanticResourceDBPackageImpl.java index a735ff5..f413397 100644 --- a/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/model/SemanticResourceDB/impl/SemanticResourceDBPackageImpl.java +++ b/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/model/SemanticResourceDB/impl/SemanticResourceDBPackageImpl.java @@ -446,12 +446,12 @@ public class SemanticResourceDBPackageImpl extends EPackageImpl implements Seman getResourceTreeNode_Children(), this.getResourceTreeNode(), this.getResourceTreeNode_Parent(), - "children", null, 0, -1, ResourceTreeNode.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, IS_COMPOSITE, !IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$ + "children", null, 0, -1, ResourceTreeNode.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$ initEReference( getResourceTreeNode_Parent(), this.getResourceTreeNode(), this.getResourceTreeNode_Children(), - "parent", null, 0, 1, ResourceTreeNode.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, !IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$ + "parent", null, 0, 1, ResourceTreeNode.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$ initEAttribute( getResourceTreeNode_Exists(), ecorePackage.getEBoolean(), @@ -498,14 +498,14 @@ public class SemanticResourceDBPackageImpl extends EPackageImpl implements Seman getSemanticDB_Roots(), this.getTreeRoot(), this.getTreeRoot_ParentDB(), - "roots", null, 0, -1, SemanticDB.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, IS_COMPOSITE, !IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$ + "roots", null, 0, -1, SemanticDB.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$ initEClass(treeRootEClass, TreeRoot.class, "TreeRoot", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); //$NON-NLS-1$ initEReference( getTreeRoot_ParentDB(), this.getSemanticDB(), this.getSemanticDB_Roots(), - "parentDB", null, 0, 1, TreeRoot.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, !IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$ + "parentDB", null, 0, 1, TreeRoot.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); //$NON-NLS-1$ initEAttribute( getTreeRoot_RootURI(), ecorePackage.getEString(), diff --git a/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/model/SemanticResourceDB/impl/TreeRootImpl.java b/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/model/SemanticResourceDB/impl/TreeRootImpl.java index d24c9b4..ff97dba 100644 --- a/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/model/SemanticResourceDB/impl/TreeRootImpl.java +++ b/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/model/SemanticResourceDB/impl/TreeRootImpl.java @@ -98,6 +98,17 @@ public class TreeRootImpl extends ResourceTreeNodeImpl implements TreeRoot { * * @generated */ + public SemanticDB basicGetParentDB() { + if (eContainerFeatureID() != SemanticResourceDBPackage.TREE_ROOT__PARENT_DB) + return null; + return (SemanticDB) eInternalContainer(); + } + + /** + * <!-- begin-user-doc --> <!-- end-user-doc --> + * + * @generated + */ public NotificationChain basicSetParentDB(SemanticDB newParentDB, NotificationChain msgs) { msgs = eBasicSetContainer((InternalEObject) newParentDB, SemanticResourceDBPackage.TREE_ROOT__PARENT_DB, msgs); return msgs; @@ -200,7 +211,9 @@ public class TreeRootImpl extends ResourceTreeNodeImpl implements TreeRoot { public Object eGet(int featureID, boolean resolve, boolean coreType) { switch (featureID) { case SemanticResourceDBPackage.TREE_ROOT__PARENT_DB : - return getParentDB(); + if (resolve) + return getParentDB(); + return basicGetParentDB(); case SemanticResourceDBPackage.TREE_ROOT__ROOT_URI : return getRootURI(); } @@ -252,7 +265,7 @@ public class TreeRootImpl extends ResourceTreeNodeImpl implements TreeRoot { public boolean eIsSet(int featureID) { switch (featureID) { case SemanticResourceDBPackage.TREE_ROOT__PARENT_DB : - return getParentDB() != null; + return basicGetParentDB() != null; case SemanticResourceDBPackage.TREE_ROOT__ROOT_URI : return ROOT_URI_EDEFAULT == null ? rootURI != null : !ROOT_URI_EDEFAULT.equals(rootURI); } diff --git a/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/model/SemanticResourceDB/util/SemanticResourceDBSwitch.java b/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/model/SemanticResourceDB/util/SemanticResourceDBSwitch.java index ea1b8d5..ea2f444 100644 --- a/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/model/SemanticResourceDB/util/SemanticResourceDBSwitch.java +++ b/bundles/org.eclipse.core.resources.semantic/src/org/eclipse/core/internal/resources/semantic/model/SemanticResourceDB/util/SemanticResourceDBSwitch.java @@ -14,14 +14,13 @@ */ package org.eclipse.core.internal.resources.semantic.model.SemanticResourceDB.util; -import java.util.List; - import org.eclipse.core.internal.resources.semantic.model.SemanticResourceDB.ResourceTreeNode; import org.eclipse.core.internal.resources.semantic.model.SemanticResourceDB.SemanticDB; import org.eclipse.core.internal.resources.semantic.model.SemanticResourceDB.SemanticResourceDBPackage; import org.eclipse.core.internal.resources.semantic.model.SemanticResourceDB.TreeRoot; -import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EPackage; +import org.eclipse.emf.ecore.util.Switch; /** * <!-- begin-user-doc --> The <b>Switch</b> for the model's inheritance @@ -34,7 +33,7 @@ import org.eclipse.emf.ecore.EObject; * @see org.eclipse.core.internal.resources.semantic.model.SemanticResourceDB.SemanticResourceDBPackage * @generated */ -public class SemanticResourceDBSwitch<T> { +public class SemanticResourceDBSwitch<T> extends Switch<T> { /** * The cached model package <!-- begin-user-doc --> <!-- end-user-doc --> * @@ -55,34 +54,16 @@ public class SemanticResourceDBSwitch<T> { } /** - * Calls <code>caseXXX</code> for each class of the model until one returns - * a non null result; it yields that result. <!-- begin-user-doc --> <!-- - * end-user-doc --> - * - * @return the first non-null result returned by a <code>caseXXX</code> - * call. - * @generated - */ - public T doSwitch(EObject theEObject) { - return doSwitch(theEObject.eClass(), theEObject); - } - - /** - * Calls <code>caseXXX</code> for each class of the model until one returns - * a non null result; it yields that result. <!-- begin-user-doc --> <!-- - * end-user-doc --> + * Checks whether this is a switch for the given package. <!-- + * begin-user-doc --> <!-- end-user-doc --> * - * @return the first non-null result returned by a <code>caseXXX</code> - * call. + * @parameter ePackage the package in question. + * @return whether this is a switch for the given package. * @generated */ - protected T doSwitch(EClass theEClass, EObject theEObject) { - if (theEClass.eContainer() == modelPackage) { - return doSwitch(theEClass.getClassifierID(), theEObject); - } else { - List<EClass> eSuperTypes = theEClass.getESuperTypes(); - return eSuperTypes.isEmpty() ? defaultCase(theEObject) : doSwitch(eSuperTypes.get(0), theEObject); - } + @Override + protected boolean isSwitchFor(EPackage ePackage) { + return ePackage == modelPackage; } /** @@ -94,6 +75,7 @@ public class SemanticResourceDBSwitch<T> { * call. * @generated */ + @Override protected T doSwitch(int classifierID, EObject theEObject) { switch (classifierID) { case SemanticResourceDBPackage.RESOURCE_TREE_NODE : { @@ -188,6 +170,7 @@ public class SemanticResourceDBSwitch<T> { * @see #doSwitch(org.eclipse.emf.ecore.EObject) * @generated */ + @Override public T defaultCase(EObject object) { return null; } diff --git a/examples/org.eclipse.core.resources.semantic.examples/META-INF/MANIFEST.MF b/examples/org.eclipse.core.resources.semantic.examples/META-INF/MANIFEST.MF index 21cfc71..4353f65 100644 --- a/examples/org.eclipse.core.resources.semantic.examples/META-INF/MANIFEST.MF +++ b/examples/org.eclipse.core.resources.semantic.examples/META-INF/MANIFEST.MF @@ -21,14 +21,14 @@ Export-Package: org.eclipse.core.resources.semantic.examples.providers, org.eclipse.core.resources.semantic.examples.remote, org.eclipse.core.resources.semantic.examples.webdav Import-Package: org.apache.http;version="4.1.4", - org.apache.http.auth;version="4.1.3", - org.apache.http.auth.params;version="4.1.3", - org.apache.http.client;version="4.1.3", - org.apache.http.client.entity;version="4.1.3", - org.apache.http.client.methods;version="4.1.3", - org.apache.http.client.params;version="4.1.3", - org.apache.http.conn.params;version="4.1.3", + org.apache.http.auth;version="4.1.2", + org.apache.http.auth.params;version="4.1.2", + org.apache.http.client;version="4.1.2", + org.apache.http.client.entity;version="4.1.2", + org.apache.http.client.methods;version="4.1.2", + org.apache.http.client.params;version="4.1.2", + org.apache.http.conn.params;version="4.1.2", org.apache.http.entity;version="4.1.4", - org.apache.http.impl.client;version="4.1.3", + org.apache.http.impl.client;version="4.1.2", org.apache.http.message;version="4.1.4", org.apache.http.params;version="4.1.4" diff --git a/features/org.eclipse.e4.resources.feature/feature.xml b/features/org.eclipse.e4.resources.feature/feature.xml index 62e12ec..694ba92 100644 --- a/features/org.eclipse.e4.resources.feature/feature.xml +++ b/features/org.eclipse.e4.resources.feature/feature.xml @@ -2,7 +2,7 @@ <feature id="org.eclipse.e4.resources.feature" label="%featureName" - version="0.12.0.qualifier" + version="0.15.0.qualifier" provider-name="%providerName" image="eclipse_update_120.jpg"> diff --git a/features/org.eclipse.e4.resources.feature/pom.xml b/features/org.eclipse.e4.resources.feature/pom.xml index 6670dd9..19433a8 100644 --- a/features/org.eclipse.e4.resources.feature/pom.xml +++ b/features/org.eclipse.e4.resources.feature/pom.xml @@ -9,7 +9,7 @@ <groupId>org.eclipse.e4</groupId> <artifactId>org.eclipse.e4.resources.feature</artifactId> - <version>0.12.0-SNAPSHOT</version> + <version>0.15.0-SNAPSHOT</version> <packaging>eclipse-feature</packaging> <build> diff --git a/tests/org.eclipse.core.resources.semantic.test/META-INF/MANIFEST.MF b/tests/org.eclipse.core.resources.semantic.test/META-INF/MANIFEST.MF index 6a95e40..d2e741f 100644 --- a/tests/org.eclipse.core.resources.semantic.test/META-INF/MANIFEST.MF +++ b/tests/org.eclipse.core.resources.semantic.test/META-INF/MANIFEST.MF @@ -2,15 +2,16 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: Unit Tests for the Semantic File System Bundle-SymbolicName: org.eclipse.core.resources.semantic.test;singleton:=true -Bundle-Version: 0.6.2.qualifier +Bundle-Version: 0.6.3.qualifier Bundle-ClassPath: . Bundle-RequiredExecutionEnvironment: J2SE-1.5 Require-Bundle: org.eclipse.core.filesystem;bundle-version="1.2.0", org.eclipse.team.core;bundle-version="3.4.2", org.eclipse.core.resources;bundle-version="3.4.2", org.eclipse.core.runtime;bundle-version="3.4.0", - org.eclipse.core.resources.semantic;bundle-version="0.6.2", + org.eclipse.core.resources.semantic;bundle-version="0.6.3", org.eclipse.jface;bundle-version="3.4.2", + org.eclipse.emf.ecore;bundle-version="2.4.2", org.eclipse.core.resources.semantic.examples;bundle-version="0.4.0" Export-Package: org.eclipse.core.resources.semantic.test, org.eclipse.core.resources.semantic.test.provider, diff --git a/tests/org.eclipse.core.resources.semantic.test/pom.xml b/tests/org.eclipse.core.resources.semantic.test/pom.xml index 70b7229..cc86ffa 100644 --- a/tests/org.eclipse.core.resources.semantic.test/pom.xml +++ b/tests/org.eclipse.core.resources.semantic.test/pom.xml @@ -9,7 +9,7 @@ <groupId>org.eclipse.e4</groupId> <artifactId>org.eclipse.core.resources.semantic.test</artifactId> - <version>0.6.2-SNAPSHOT</version> + <version>0.6.3-SNAPSHOT</version> <packaging>eclipse-test-plugin</packaging> </project> diff --git a/tests/org.eclipse.core.resources.semantic.test/src/org/eclipse/core/resources/semantic/test/TestMetadataPersistenceManager.java b/tests/org.eclipse.core.resources.semantic.test/src/org/eclipse/core/resources/semantic/test/TestMetadataPersistenceManager.java new file mode 100644 index 0000000..957e84c --- /dev/null +++ b/tests/org.eclipse.core.resources.semantic.test/src/org/eclipse/core/resources/semantic/test/TestMetadataPersistenceManager.java @@ -0,0 +1,288 @@ +/******************************************************************************* + * Copyright (c) 2013 SAP AG. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Eduard Bartsch (SAP AG) - initial API and implementation + *******************************************************************************/ +package org.eclipse.core.resources.semantic.test; + +import java.io.File; +import java.io.IOException; +import java.util.UUID; + +import org.eclipse.core.internal.resources.semantic.SemanticMetadataPersistenceManager; +import org.eclipse.core.internal.resources.semantic.model.SemanticResourceDB.SemanticDB; +import org.eclipse.core.internal.resources.semantic.model.SemanticResourceDB.SemanticResourceDBFactory; +import org.eclipse.core.internal.resources.semantic.model.SemanticResourceDB.TreeNodeType; +import org.eclipse.core.internal.resources.semantic.model.SemanticResourceDB.TreeRoot; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +/** + * + */ +public class TestMetadataPersistenceManager { + private static final String TEST_ROOT = "testRoot"; + private static final String TEST_ROOT2 = "testRoot2"; + private File rootFolder; + private SemanticMetadataPersistenceManager mgr; + private SemanticMetadataPersistenceManager mgr2; + private SemanticMetadataPersistenceManager mgr3; + + @Before + public void beforeMethod() throws Exception { + this.rootFolder = createTestRoot(); + mgr = new SemanticMetadataPersistenceManager(this.rootFolder); + mgr2 = new SemanticMetadataPersistenceManager(this.rootFolder); + mgr3 = new SemanticMetadataPersistenceManager(this.rootFolder); + } + + @After + public void afterMethod() throws Exception { + deleteRecursively(this.rootFolder); + } + + @Test + public void test_GivenNoMetadataExists_WhenInitAndSave_ThenMetadataFileIsCreated() throws Exception { + mgr.init(); + + File metadataLocation = mgr.getMetadataFile(null); + + Assert.assertTrue(rootFolder.exists()); + Assert.assertFalse(metadataLocation.exists()); + + mgr.saveSemanticDB(null); + + Assert.assertTrue("metadata file must be created", metadataLocation.exists()); + } + + @Test + public void test_GivenNoMetadataExists_WhenInitAddOneExistingRootAndSaveAll_ThenTwoMetadataFileAreCreated() throws Exception { + mgr.init(); + + SemanticDB db = mgr.getSemanticDB(); + + db.getRoots().add(createRootNode(TEST_ROOT, true)); + + mgr.saveSemanticDB(null); + + Assert.assertTrue("metadata file must be created", mgr.getMetadataFile(null).exists()); + Assert.assertTrue("metadata file must be created", mgr.getMetadataFile(TEST_ROOT).exists()); + } + + @Test + public void test_GivenNoMetadataExists_WhenInitAddTwoExistingRootsAndSaveAll_ThenThreeMetadataFileAreCreated() throws Exception { + mgr.init(); + + SemanticDB db = mgr.getSemanticDB(); + + db.getRoots().add(createRootNode(TEST_ROOT, true)); + + db.getRoots().add(createRootNode(TEST_ROOT2, true)); + + mgr.saveSemanticDB(null); + + Assert.assertTrue("metadata file must be created", mgr.getMetadataFile(null).exists()); + Assert.assertTrue("metadata file must be created", mgr.getMetadataFile(TEST_ROOT).exists()); + Assert.assertTrue("metadata file must be created", mgr.getMetadataFile(TEST_ROOT2).exists()); + } + + @Test + public void test_GivenNoMetadataExists_WhenInitAddTwoExistingRootsAndSaveOne_ThenTwoMetadataFileAreCreated() throws Exception { + mgr.init(); + + SemanticDB db = mgr.getSemanticDB(); + + db.getRoots().add(createRootNode(TEST_ROOT, true)); + + db.getRoots().add(createRootNode(TEST_ROOT2, true)); + + mgr.saveSemanticDB(TEST_ROOT); + + Assert.assertTrue("metadata file must be created", mgr.getMetadataFile(null).exists()); + Assert.assertTrue("metadata file must be created", mgr.getMetadataFile(TEST_ROOT).exists()); + Assert.assertFalse("metadata file must not be created", mgr.getMetadataFile(TEST_ROOT2).exists()); + } + + @Test + public void test_GivenOneRootExists_WhenInit_ThenOneRootIsPresent() throws Exception { + // given + mgr.init(); + mgr.getSemanticDB().getRoots().add(createRootNode(TEST_ROOT, true)); + mgr.saveSemanticDB(null); + + // when + mgr2.init(); + + // then + SemanticDB db = mgr2.getSemanticDB(); + + Assert.assertEquals(1, db.getRoots().size()); + Assert.assertEquals(TEST_ROOT, db.getRoots().get(0).getName()); + } + + @Test + public void test_GivenTwoRootsExists_WhenLoadAndSaveOnlyOneRoot_ThenOnlyTwoMetadataFilesAreChanged() throws Exception { + // given + mgr.init(); + mgr.getSemanticDB().getRoots().add(createRootNode(TEST_ROOT, true)); + mgr.getSemanticDB().getRoots().add(createRootNode(TEST_ROOT2, true)); + mgr.saveSemanticDB(null); + + long lastModification = mgr.getMetadataFile(null).lastModified(); + long lastModification1 = mgr.getMetadataFile(TEST_ROOT).lastModified(); + long lastModification2 = mgr.getMetadataFile(TEST_ROOT2).lastModified(); + + Thread.sleep(1011); + + // when + mgr2.init(); + + mgr2.saveSemanticDB(TEST_ROOT); + + // then + long newModification = mgr2.getMetadataFile(null).lastModified(); + long newModification1 = mgr2.getMetadataFile(TEST_ROOT).lastModified(); + long newModification2 = mgr2.getMetadataFile(TEST_ROOT2).lastModified(); + + Assert.assertTrue("metadata file must be modified", lastModification != newModification); + Assert.assertTrue("metadata file must be modified", lastModification1 != newModification1); + Assert.assertTrue("metadata file must not be modified", lastModification2 == newModification2); + } + + @Test + public void test_GivenTwoRootsExistsInOldMetadata_WhenLoadAndMigrate_ThenThreeMetadataFilesAreCreated() throws Exception { + // given + + // use mgr.init() to create a folder that simulates metadata + // content before migrations + mgr.init(); + + mgr2.initSemanticDB(); + mgr2.getSemanticDB().getRoots().add(createRootNode(TEST_ROOT, true)); + mgr2.getSemanticDB().getRoots().add(createRootNode(TEST_ROOT2, true)); + + Assert.assertFalse("metadata file must not be created", mgr2.getMetadataFile(null).exists()); + Assert.assertFalse("metadata file must not be created", mgr2.getMetadataFile(TEST_ROOT).exists()); + Assert.assertFalse("metadata file must not be created", mgr2.getMetadataFile(TEST_ROOT2).exists()); + + // when + mgr2.migrateSemanticDB(); + + // then + Assert.assertTrue("metadata file must be created", mgr2.getMetadataFile(null).exists()); + Assert.assertTrue("metadata file must be created", mgr2.getMetadataFile(TEST_ROOT).exists()); + Assert.assertTrue("metadata file must be created", mgr2.getMetadataFile(TEST_ROOT2).exists()); + } + + @Test + public void test_GivenOneRootExists_WhenSetRootNotExistsSaveAndLoad_ThenOneMetadataFileIsPresent() throws Exception { + // given + mgr.init(); + mgr.getSemanticDB().getRoots().add(createRootNode(TEST_ROOT, true)); + mgr.saveSemanticDB(null); + + // when + SemanticDB db = mgr.getSemanticDB(); + + TreeRoot root = db.getRoots().get(0); + root.setExists(false); + + mgr.saveSemanticDB(null); + + mgr2.init(); + + // then + Assert.assertTrue("metadata file must be created", mgr.getMetadataFile(null).exists()); + Assert.assertFalse("metadata file must not be created", mgr.getMetadataFile(TEST_ROOT).exists()); + } + + @Test + public void test_GivenOneRootExists_WhenRemoveRootSaveAndLoad_ThenOneMetadataFileIsPresent() throws Exception { + // given + mgr.init(); + mgr.getSemanticDB().getRoots().add(createRootNode(TEST_ROOT, true)); + mgr.saveSemanticDB(null); + + // when + mgr.getSemanticDB().getRoots().remove(0); + + mgr.saveSemanticDB(null); + + mgr2.init(); + + // then + Assert.assertTrue("metadata file must be created", mgr.getMetadataFile(null).exists()); + Assert.assertFalse("metadata file must not be created", mgr.getMetadataFile(TEST_ROOT).exists()); + } + + @Test + public void test_GivenTwoRootsExists_WhenRemoveRootSaveAndLoad_ThenOnlyTwoMetadataFilesArePresent() throws Exception { + // given + mgr.init(); + mgr.getSemanticDB().getRoots().add(createRootNode(TEST_ROOT, true)); + mgr.getSemanticDB().getRoots().add(createRootNode(TEST_ROOT2, true)); + mgr.saveSemanticDB(null); + + // when + mgr2.init(); + + mgr2.getSemanticDB().getRoots().remove(0); + + mgr2.saveSemanticDB(null); + + mgr3.init(); + + // then + Assert.assertTrue("metadata file must be created", mgr3.getMetadataFile(null).exists()); + Assert.assertFalse("metadata file must not be created", mgr3.getMetadataFile(TEST_ROOT).exists()); + Assert.assertTrue("metadata file must be created", mgr3.getMetadataFile(TEST_ROOT2).exists()); + + } + + // Helper methods + + private TreeRoot createRootNode(String name, boolean exists) { + TreeRoot root = SemanticResourceDBFactory.eINSTANCE.createTreeRoot(); + + root.setName(name); + root.setExists(exists); + root.setPath("/" + name); //$NON-NLS-1$ + root.setType(TreeNodeType.PROJECT); + + return root; + } + + private File createTestRoot() { + String tmpdir = System.getProperty("java.io.tmpdir"); + String uuid = UUID.randomUUID().toString(); + File uniqueRoot = new File(tmpdir, uuid); + uniqueRoot.deleteOnExit(); + return uniqueRoot; + } + + private void deleteRecursively(File root) throws IOException { + if (root.exists()) { + if (root.isFile()) { + root.delete(); + } else { + File[] files = root.listFiles(); + if (files != null) { + for (File file : files) { + deleteRecursively(file); + } + } + if (!root.delete()) { + throw new IOException("Unable to delete " + root.getAbsolutePath()); + } + } + } + } + +} diff --git a/tests/org.eclipse.core.resources.semantic.test/src/org/eclipse/core/resources/semantic/test/TestSemanticFileSystem.java b/tests/org.eclipse.core.resources.semantic.test/src/org/eclipse/core/resources/semantic/test/TestSemanticFileSystem.java new file mode 100644 index 0000000..c91ae67 --- /dev/null +++ b/tests/org.eclipse.core.resources.semantic.test/src/org/eclipse/core/resources/semantic/test/TestSemanticFileSystem.java @@ -0,0 +1,204 @@ +/******************************************************************************* + * Copyright (c) 2013 SAP AG. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Eduard Bartsch (SAP AG) - initial API and implementation + *******************************************************************************/ +package org.eclipse.core.resources.semantic.test; + +import static org.junit.Assert.assertTrue; + +import java.io.File; +import java.io.IOException; +import java.net.URI; +import java.util.UUID; + +import org.eclipse.core.filesystem.IFileStore; +import org.eclipse.core.internal.resources.semantic.SemanticFileSystem; +import org.eclipse.core.resources.semantic.ISemanticFileSystem; +import org.eclipse.core.resources.semantic.spi.ISemanticFileStore; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +/** + * + */ +public class TestSemanticFileSystem { + private static final String TEST_FOLDER2 = "testFolder2"; + private static final String TEST2_PROJECT_XMI_FILENAME = "$.test2.xmi"; + private static final String TEST_PROJECT_XMI_FILENAME = "$.test.xmi"; + private static final String TEST_FOLDER = "testFolder"; + private static final String TEST_ROOT2 = "test2"; + private static final String TEST_ROOT = "test"; + // private static final String TEST_ROOT = "testRoot"; + // private static final String TEST_ROOT2 = "testRoot2"; + private File rootFolder; + private SemanticFileSystem fs; + + @Before + public void beforeMethod() throws Exception { + this.rootFolder = createTestRoot(); + } + + @After + public void afterMethod() throws Exception { + deleteRecursively(this.rootFolder); + } + + @Test + public void test_GivenNoMetadataExists_WhenCreateSFSaddFolderAndSave_ThenMetadataFileIsCreated() throws Exception { + + // when + fs = new SemanticFileSystem(this.rootFolder); + + IFileStore store = fs.getStore(new URI(ISemanticFileSystem.SCHEME + ":/" + TEST_ROOT)); + + store.mkdir(0, null); + + ((ISemanticFileStore) store).addChildFolder(TEST_FOLDER); + + // then + File metadataLocation = new File(fs.getPathToDb()); + File testMetadataFile = new File(metadataLocation.getParentFile(), TEST_PROJECT_XMI_FILENAME); + + assertTrue(rootFolder.exists()); + assertTrue("metadata file must be created", metadataLocation.exists()); + assertTrue("project-specific metadata file must be created", testMetadataFile.exists()); + } + + @Test + public void test_GivenNoMetadataExists_WhenCreateSFSaddFileAndSave_ThenMetadataFileIsCreated() throws Exception { + + // when + fs = new SemanticFileSystem(this.rootFolder); + + IFileStore store = fs.getStore(new URI(ISemanticFileSystem.SCHEME + ":/" + TEST_ROOT)); + + store.mkdir(0, null); + + ((ISemanticFileStore) store).addChildFile("testFile"); + + // then + File metadataLocation = new File(fs.getPathToDb()); + File testMetadataFile = new File(metadataLocation.getParentFile(), TEST_PROJECT_XMI_FILENAME); + + assertTrue(rootFolder.exists()); + assertTrue("metadata file must be created", metadataLocation.exists()); + assertTrue("project-specific metadata file must be created", testMetadataFile.exists()); + } + + @Test + public void test_GivenNoMetadataExists_WhenCreateSFSaddTwoNodesAndSave_ThenTwoMetadataFileAreCreated() throws Exception { + + // when + fs = new SemanticFileSystem(this.rootFolder); + + IFileStore store = fs.getStore(new URI(ISemanticFileSystem.SCHEME + ":/" + TEST_ROOT)); + + store.mkdir(0, null); + + ((ISemanticFileStore) store).addChildFolder(TEST_FOLDER); + + store = fs.getStore(new URI(ISemanticFileSystem.SCHEME + ":/" + TEST_ROOT2)); + + store.mkdir(0, null); + + ((ISemanticFileStore) store).addChildFolder(TEST_FOLDER); + + // then + File metadataLocation = new File(fs.getPathToDb()); + File testMetadataFile = new File(metadataLocation.getParentFile(), TEST_PROJECT_XMI_FILENAME); + File test2MetadataFile = new File(metadataLocation.getParentFile(), TEST2_PROJECT_XMI_FILENAME); + + assertTrue(rootFolder.exists()); + assertTrue("metadata file must be created", metadataLocation.exists()); + assertTrue("project-specific metadata file must be created", testMetadataFile.exists()); + assertTrue("project-specific metadata file must be created", test2MetadataFile.exists()); + } + + @Test + public void test_GivenTwoProjectsExists_WhenLoadAndChangeOnlyOneProject_ThenOnlyTwoMetadataFilesAreChanged() throws Exception { + // given + fs = new SemanticFileSystem(this.rootFolder); + + IFileStore store = fs.getStore(new URI(ISemanticFileSystem.SCHEME + ":/" + TEST_ROOT)); + + store.mkdir(0, null); + + ((ISemanticFileStore) store).addChildFolder(TEST_FOLDER); + + store = fs.getStore(new URI(ISemanticFileSystem.SCHEME + ":/" + TEST_ROOT2)); + + store.mkdir(0, null); + + ((ISemanticFileStore) store).addChildFolder(TEST_FOLDER); + + File metadataLocation = new File(fs.getPathToDb()); + File testMetadataFile = new File(metadataLocation.getParentFile(), TEST_PROJECT_XMI_FILENAME); + File test2MetadataFile = new File(metadataLocation.getParentFile(), TEST2_PROJECT_XMI_FILENAME); + + long lastModification = metadataLocation.lastModified(); + long lastModification1 = testMetadataFile.lastModified(); + long lastModification2 = test2MetadataFile.lastModified(); + + Thread.sleep(1011); + + // when + fs = new SemanticFileSystem(this.rootFolder); + + store = fs.getStore(new URI(ISemanticFileSystem.SCHEME + ":/" + TEST_ROOT)); + + ((ISemanticFileStore) store).addChildFolder(TEST_FOLDER2); + + // then + assertTrue("folder must exist", store.getChild(TEST_FOLDER).fetchInfo().exists()); + + long newModification = metadataLocation.lastModified(); + long newModification1 = testMetadataFile.lastModified(); + long newModification2 = test2MetadataFile.lastModified(); + + assertTrue("metadata file must be modified", lastModification != newModification); + assertTrue("metadata file must be modified", lastModification1 != newModification1); + assertTrue("metadata file must not be modified", lastModification2 == newModification2); + + fs = new SemanticFileSystem(this.rootFolder); + + store = fs.getStore(new URI(ISemanticFileSystem.SCHEME + ":/" + TEST_ROOT)); + + assertTrue("folder must exist", store.getChild(TEST_FOLDER2).fetchInfo().exists()); + } + + // Helper methods + + private File createTestRoot() { + String tmpdir = System.getProperty("java.io.tmpdir"); + String uuid = UUID.randomUUID().toString(); + File uniqueRoot = new File(tmpdir, uuid); + uniqueRoot.deleteOnExit(); + return uniqueRoot; + } + + private void deleteRecursively(File root) throws IOException { + if (root.exists()) { + if (root.isFile()) { + root.delete(); + } else { + File[] files = root.listFiles(); + if (files != null) { + for (File file : files) { + deleteRecursively(file); + } + } + if (!root.delete()) { + throw new IOException("Unable to delete " + root.getAbsolutePath()); + } + } + } + } + +} diff --git a/tests/org.eclipse.core.resources.semantic.test/src/org/eclipse/core/resources/semantic/test/suite/SfsTestSuite.java b/tests/org.eclipse.core.resources.semantic.test/src/org/eclipse/core/resources/semantic/test/suite/SfsTestSuite.java index 4a4f9a1..694c964 100644 --- a/tests/org.eclipse.core.resources.semantic.test/src/org/eclipse/core/resources/semantic/test/suite/SfsTestSuite.java +++ b/tests/org.eclipse.core.resources.semantic.test/src/org/eclipse/core/resources/semantic/test/suite/SfsTestSuite.java @@ -12,6 +12,8 @@ package org.eclipse.core.resources.semantic.test.suite; import org.eclipse.core.resources.semantic.test.TestCacheService; +import org.eclipse.core.resources.semantic.test.TestMetadataPersistenceManager; +import org.eclipse.core.resources.semantic.test.TestSemanticFileSystem; import org.eclipse.core.resources.semantic.test.TestsCachingProvider; import org.eclipse.core.resources.semantic.test.TestsDefaultContentProvider; import org.eclipse.core.resources.semantic.test.TestsFederatingProvider; @@ -33,6 +35,8 @@ import org.junit.runners.Suite; TestsFederatingProvider2.class,// TestsNullContentProvider.class,// TestCacheService.class,// + TestMetadataPersistenceManager.class,// + TestSemanticFileSystem.class,// TestsLinkedResources.class}) public class SfsTestSuite { // the suite |