Author: rombert Date: Mon Oct 5 11:14:45 2015 New Revision: 1706803 URL: http://svn.apache.org/viewvc?rev=1706803&view=rev Log: SLING-3766 - Store the project's content sync root property in the filesystem
Fix + tests Modified: sling/trunk/tooling/ide/eclipse-core/plugin.xml sling/trunk/tooling/ide/eclipse-core/src/org/apache/sling/ide/eclipse/core/ProjectUtil.java sling/trunk/tooling/ide/eclipse-test/src/org/apache/sling/ide/test/impl/ProjectUtilTest.java Modified: sling/trunk/tooling/ide/eclipse-core/plugin.xml URL: http://svn.apache.org/viewvc/sling/trunk/tooling/ide/eclipse-core/plugin.xml?rev=1706803&r1=1706802&r2=1706803&view=diff ============================================================================== --- sling/trunk/tooling/ide/eclipse-core/plugin.xml (original) +++ sling/trunk/tooling/ide/eclipse-core/plugin.xml Mon Oct 5 11:14:45 2015 @@ -239,4 +239,10 @@ </exclude> </validator> </extension> + + <!-- Store project preferences in the filesystem --> + <extension id="org.apache.sling.ide.preferences" point="org.eclipse.core.runtime.preferences"> + <scope name="project" class="org.eclipse.core.internal.resources.ProjectPreferences"> + </scope> + </extension> </plugin> Modified: sling/trunk/tooling/ide/eclipse-core/src/org/apache/sling/ide/eclipse/core/ProjectUtil.java URL: http://svn.apache.org/viewvc/sling/trunk/tooling/ide/eclipse-core/src/org/apache/sling/ide/eclipse/core/ProjectUtil.java?rev=1706803&r1=1706802&r2=1706803&view=diff ============================================================================== --- sling/trunk/tooling/ide/eclipse-core/src/org/apache/sling/ide/eclipse/core/ProjectUtil.java (original) +++ sling/trunk/tooling/ide/eclipse-core/src/org/apache/sling/ide/eclipse/core/ProjectUtil.java Mon Oct 5 11:14:45 2015 @@ -29,6 +29,7 @@ import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.ProjectScope; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; @@ -36,11 +37,16 @@ import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.QualifiedName; import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.preferences.IEclipsePreferences; +import org.eclipse.core.runtime.preferences.IScopeContext; +import org.osgi.service.prefs.BackingStoreException; public abstract class ProjectUtil { - private static final String PROPERTY_SYNC_ROOT = "sync_root"; + private static final String PROPERTY_SYNC_ROOT = Activator.PLUGIN_ID + ".content_sync_root"; private static final String PROPERTY_SYNC_ROOT_DEFAULT_VALUE = "jcr_root"; + + private static final QualifiedName PROPERTY_SYNC_ROOT_OLD = new QualifiedName(Activator.PLUGIN_ID, "sync_root"); public static IFolder getSyncDirectory(IProject project) { if (project==null) { @@ -74,13 +80,47 @@ public abstract class ProjectUtil { * @return the value of the sync directory */ public static IPath getSyncDirectoryValue(IProject project) { - String value = null; + + // for compatibility reasons, read the old value first + String oldValue = null; try { - value = project.getPersistentProperty(new QualifiedName(Activator.PLUGIN_ID, PROPERTY_SYNC_ROOT)); + oldValue = project.getPersistentProperty(PROPERTY_SYNC_ROOT_OLD); } catch (CoreException e) { - Activator.getDefault().getPluginLogger().error(e.getMessage(), e); + Activator.getDefault().getPluginLogger().trace("Failed retrieving old values for content sync root for project " + project.getName(), e); } + + // read a value from the new store, returning a default if none is found + IScopeContext projectScope = new ProjectScope(project); + IEclipsePreferences projectNode = projectScope.getNode(Activator.PLUGIN_ID); + if ( projectNode == null ) { + String value; + // try to read from old values + if ( oldValue != null ) { + value = oldValue; + } else { + value = PROPERTY_SYNC_ROOT_DEFAULT_VALUE; + } + return Path.fromOSString(value); + } + + // if no new value if found and an old value exists, use the old value and save it in the new store + String value = projectNode.get(PROPERTY_SYNC_ROOT, null); + if ( value == null && oldValue != null ) { + value = oldValue; + setSyncDirectoryPath(project, Path.fromPortableString(value)); + } + + // it is now safe to delete the value from the old store + if ( oldValue != null ) { + try { + project.setPersistentProperty(PROPERTY_SYNC_ROOT_OLD, null); + } catch (CoreException e) { + Activator.getDefault().getPluginLogger().error(e.getMessage(), e); + } + } + + // convert and return // TODO central place for defaults if (value == null) { return Path.fromOSString(PROPERTY_SYNC_ROOT_DEFAULT_VALUE); @@ -109,11 +149,16 @@ public abstract class ProjectUtil { * @param path the value */ public static void setSyncDirectoryPath(IProject project, IPath path) { - - try { - project.setPersistentProperty(new QualifiedName(Activator.PLUGIN_ID, PROPERTY_SYNC_ROOT), path.toPortableString()); - } catch (CoreException e) { - Activator.getDefault().getPluginLogger().error(e.getMessage(), e); + + IScopeContext projectScope = new ProjectScope(project); + IEclipsePreferences projectNode = projectScope.getNode(Activator.PLUGIN_ID); + if ( projectNode != null ) { + projectNode.put(PROPERTY_SYNC_ROOT, path.toPortableString()); + try { + projectNode.flush(); + } catch (BackingStoreException e) { + Activator.getDefault().getPluginLogger().error(e.getMessage(), e); + } } } Modified: sling/trunk/tooling/ide/eclipse-test/src/org/apache/sling/ide/test/impl/ProjectUtilTest.java URL: http://svn.apache.org/viewvc/sling/trunk/tooling/ide/eclipse-test/src/org/apache/sling/ide/test/impl/ProjectUtilTest.java?rev=1706803&r1=1706802&r2=1706803&view=diff ============================================================================== --- sling/trunk/tooling/ide/eclipse-test/src/org/apache/sling/ide/test/impl/ProjectUtilTest.java (original) +++ sling/trunk/tooling/ide/eclipse-test/src/org/apache/sling/ide/test/impl/ProjectUtilTest.java Mon Oct 5 11:14:45 2015 @@ -17,6 +17,7 @@ package org.apache.sling.ide.test.impl; import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.nullValue; import static org.junit.Assert.assertThat; import java.io.ByteArrayInputStream; @@ -24,10 +25,13 @@ import java.io.ByteArrayInputStream; import org.apache.sling.ide.eclipse.core.ProjectUtil; import org.apache.sling.ide.test.impl.helpers.ProjectAdapter; import org.apache.sling.ide.test.impl.helpers.TemporaryProject; +import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.QualifiedName; +import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -35,24 +39,35 @@ public class ProjectUtilTest { @Rule public TemporaryProject projectRule = new TemporaryProject(); + + private IProject contentProject; + private ProjectAdapter project; - @Test - public void slingContentProjectSyncedResourcesAreExportable() throws CoreException, InterruptedException { - + @Before + public void createEmptyContentProject() throws Exception { // create faceted project - IProject contentProject = projectRule.getProject(); + contentProject = projectRule.getProject(); - ProjectAdapter project = new ProjectAdapter(contentProject); + project = new ProjectAdapter(contentProject); project.addNatures("org.eclipse.wst.common.project.facet.core.nature"); // install bundle facet project.installFacet("sling.content", "1.0"); + // create filter file project.createVltFilterWithRoots(); + // create content sync dir + project.ensureDirectoryExists(Path.fromPortableString("jcr_root")); + + } + + @Test + public void slingContentProjectSyncedResourcesAreExportable() throws CoreException, InterruptedException { + + project.createOrUpdateFile(Path.fromPortableString("jcr_root/test/hello.txt"), new ByteArrayInputStream( "goodbye, world".getBytes())); - IPath filterPath = ProjectUtil.findFilterPath(contentProject); assertThat("filterPath.absolute", filterPath.isAbsolute(), equalTo(true)); @@ -60,4 +75,44 @@ public class ProjectUtilTest { equalTo("META-INF/vault/filter.xml")); } + + @Test + public void defaultContentSyncRootIsReturned() throws Exception { + + IFolder syncDirectory = ProjectUtil.getSyncDirectory(contentProject); + + assertThat(syncDirectory.getProjectRelativePath(), equalTo(Path.fromPortableString("jcr_root"))); + } + + @Test + public void customContentSyncRootIsObeyed() throws Exception { + + IPath contentSyncPath = Path.fromPortableString("src/main/content/jcr_root"); + + project.ensureDirectoryExists(contentSyncPath); + ProjectUtil.setSyncDirectoryPath(contentProject, contentSyncPath); + + assertThat(ProjectUtil.getSyncDirectory(contentProject).getProjectRelativePath(), equalTo(contentSyncPath)); + } + + @Test + public void oldContentSyncRootIsMigrated() throws Exception { + + QualifiedName oldPropertyQName = new QualifiedName("org.apache.sling.ide.eclipse-core", "sync_root"); + + IPath contentSyncPath = Path.fromPortableString("src/main/content/jcr_root"); + + project.ensureDirectoryExists(contentSyncPath); + + // simulate the old property being set + contentProject.setPersistentProperty(oldPropertyQName, contentSyncPath.toString()); + + // query the data through the API, old value should be obeyed + assertThat("Old sync_root not obeyed", ProjectUtil.getSyncDirectory(contentProject).getProjectRelativePath(), equalTo(contentSyncPath)); + // the old store should no longer have the config value + assertThat("Old property not removed", contentProject.getPersistentProperty(oldPropertyQName), nullValue()); + // a second query should work just the same, to make sure that after deleting the data from the old store we get the right value back + assertThat("sync_root not obeyed after old store for property was deleted", + ProjectUtil.getSyncDirectory(contentProject).getProjectRelativePath(), equalTo(contentSyncPath)); + } }