Uploaded image for project: 'ModeShape'
  1. ModeShape
  2. MODE-2562

Backup and restore converts two backslashes in a single backslash

    Details

    • Type: Bug
    • Status: Resolved (View Workflow)
    • Priority: Major
    • Resolution: Done
    • Affects Version/s: 4.5.0.Final
    • Fix Version/s: 5.0.0.Final, 4.6.0.Final
    • Component/s: None
    • Labels:
      None
    • Steps to Reproduce:
      Hide
      1. Set a string property of any node to a value containing '\\'
      2. Backup the repository using org.modeshape.jcr.api.RepositoryManager.backupRepository()
      3. Restore the repository using org.modeshape.jcr.api.RepositoryManager.restoreRepository()
      4. The value of the property would be different, having only a single '\' instead of '\\'
      Show
      Set a string property of any node to a value containing '\\' Backup the repository using org.modeshape.jcr.api.RepositoryManager.backupRepository() Restore the repository using org.modeshape.jcr.api.RepositoryManager.restoreRepository() The value of the property would be different, having only a single '\' instead of '\\'

      Description

      If you create and then restore a backup using org.modeshape.jcr.api.RepositoryManager, all string properties containing two backslashes '\\', are replaced to contain a single backslash '\'.

      For example if you have a value "foo\\bar", after you backup and restore the value would be "foo\bar"

      Here's a simple program, which shows the effect.

      This is the output:

      Jan 22, 2016 3:21:58 PM org.modeshape.common.logging.LogFactory <clinit>
      INFO: No custom logger, SLF4J implementation or Log4j located in the classpath. ModeShape will use the JDK logger for logging.
      Jan 22, 2016 3:21:59 PM org.modeshape.jcr.ModeShape <clinit>
      INFO: ModeShape version 4.5.0.Final
      Jan 22, 2016 3:22:00 PM org.infinispan.factories.GlobalComponentRegistry start
      INFO: ISPN000128: Infinispan version: Infinispan 'Insanely Bad Elf' 7.2.4.Final
      Jan 22, 2016 3:22:00 PM org.infinispan.transaction.lookup.GenericTransactionManagerLookup useDummyTM
      WARN: ISPN000104: Falling back to DummyTransactionManager from Infinispan
      Values before creating backup:
      The value of 'oneBackslash' is 'one\backslash'
      The value of 'twoBackslashes' is 'two\\backslashes'
      The value of 'threeBackslashes' is 'three\\\backslashes'
      Values after restoring backup:
      The value of 'oneBackslash' is 'one\backslash'
      The value of 'twoBackslashes' is 'two\backslashes'
      The value of 'threeBackslashes' is 'three\\backslashes'
      

      And here is the program itself

      import java.io.File;
      import java.net.URL;
      import java.nio.file.Files;
      
      import javax.jcr.Repository;
      import javax.jcr.Session;
      
      import org.infinispan.schematic.document.ParsingException;
      import org.modeshape.common.collection.Problems;
      import org.modeshape.jcr.ModeShapeEngine;
      import org.modeshape.jcr.RepositoryConfiguration;
      import org.modeshape.jcr.api.RepositoryManager;
      
      public class ModeShapeBug {
          private static final String REPO_CONFIG_FILE = "repo-config.json";
          private static final String WORKSPACE_NAME = "configuration";
      
          private static URL repositoryUrl;
          private static ModeShapeEngine engine;
          private static RepositoryConfiguration config;
      
          public static void main(String[] args) throws Exception {
              repositoryUrl = ModeShapeBug.class.getClassLoader().getResource(REPO_CONFIG_FILE);
              engine = new ModeShapeEngine();
      
              engine.start();
              try {
                  config = readConfig(repositoryUrl);
                  engine.deploy(config);
                  File tempDir = Files.createTempDirectory("modeshape-restore-bug-").toFile();
      
                  String oneBackslash = "oneBackslash";
                  String twoBackslashes = "twoBackslashes";
                  String threeBackslashes = "threeBackslashes";
      
                  setPropertyValue(oneBackslash, "one\\backslash");
                  setPropertyValue(twoBackslashes, "two\\\\backslashes");
                  setPropertyValue(threeBackslashes, "three\\\\\\backslashes");
      
                  System.out.printf("Values before creating backup:\n");
                  printPropertyValue(oneBackslash);
                  printPropertyValue(twoBackslashes);
                  printPropertyValue(threeBackslashes);
      
                  createBackup(tempDir);
                  restoreBackup(tempDir);
      
                  System.out.printf("Values after restoring backup:\n");
                  printPropertyValue(oneBackslash);
                  printPropertyValue(twoBackslashes);
                  printPropertyValue(threeBackslashes);
              } finally {
                  engine.shutdown().get();
              }
          }
      
          private static String printPropertyValue(String property) throws Exception {
              Session session = startSession();
              try {
                  String value = session.getRootNode().getProperty(property).getString();
                  System.out.printf("The value of '%s' is '%s'\n", property, value);
                  return value;
              } finally {
                  session.logout();
              }
          }
      
          private static void setPropertyValue(String property, String value) throws Exception {
              Session session = startSession();
              try {
                  session.getRootNode().setProperty(property, value);
                  session.save();
              } finally {
                  session.logout();
              }
          }
      
          private static void createBackup(File tempDir) throws Exception {
              Session session = startSession();
              try {
                  RepositoryManager repositoryManager =
                          ((org.modeshape.jcr.api.Session)session).getWorkspace().getRepositoryManager();
                  org.modeshape.jcr.api.Problems problems = repositoryManager.backupRepository(tempDir);
                  if (problems.hasProblems()){
                      throw new RuntimeException("Problems creating backup: " + problems);
                  }
              } finally {
                  session.logout();
              }
          }
      
          private static void restoreBackup(File tempDir) throws Exception {
              Session session = startSession();
              try {
                  RepositoryManager repositoryManager =
                          ((org.modeshape.jcr.api.Session)session).getWorkspace().getRepositoryManager();
                  org.modeshape.jcr.api.Problems problems = repositoryManager.restoreRepository(tempDir);
                  if (problems.hasProblems()){
                      throw new RuntimeException("Problems restoring backup: " + problems);
                  }
              } finally {
                  session.logout();
              }
          }
      
          private static RepositoryConfiguration readConfig(URL repositoryUrl) throws ParsingException {
              RepositoryConfiguration config = RepositoryConfiguration.read(repositoryUrl);
              Problems problems = config.validate();
              if (problems.hasErrors()) {
                  throw new RuntimeException("Problems starting the engine: " + problems);
              }
              return config;
          }
      
          private static Session startSession()
                  throws Exception {
              Repository repository = engine.getRepository(config.getName());
              Session session = repository.login(WORKSPACE_NAME);
              return session;
          }
      }
      

      I'm also going to attach it as a maven project, so you can take a better look at it if needed.

        Gliffy Diagrams

          Attachments

            Activity

              People

              • Assignee:
                hchiorean Horia Chiorean
                Reporter:
                kiril.raychev Kiril Raychev
              • Votes:
                0 Vote for this issue
                Watchers:
                3 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: