Read files from a nested folder in a jar











up vote
0
down vote

favorite












In my spring-boot web app I have the following structure:



- resources
- properties
- profiles
- profile1.properties
- profile2.properties
- profile3.properties


I would like to read all the properties from all the files under the profiles folder. The solution should work for all of the following:




  • Running from an IDE

  • Running from a jar

  • Running on a windows server

  • Running on a linux server


I've encountered a few solution proposals but couldn't actually find one that works.










share|improve this question
























  • Q: What "solution proposals"? Did they involve .getResourceAsStream()? What problem(s)/limitation(s) did you encounter?
    – paulsm4
    Nov 21 at 20:11












  • Use Spring resource loading and use classpath:profiles/profile1.properties to load it.
    – M. Deinum
    Nov 21 at 20:25










  • @Denium the file names are unknown, I only know the the location of the profiles folder.
    – forhas
    Nov 21 at 20:31















up vote
0
down vote

favorite












In my spring-boot web app I have the following structure:



- resources
- properties
- profiles
- profile1.properties
- profile2.properties
- profile3.properties


I would like to read all the properties from all the files under the profiles folder. The solution should work for all of the following:




  • Running from an IDE

  • Running from a jar

  • Running on a windows server

  • Running on a linux server


I've encountered a few solution proposals but couldn't actually find one that works.










share|improve this question
























  • Q: What "solution proposals"? Did they involve .getResourceAsStream()? What problem(s)/limitation(s) did you encounter?
    – paulsm4
    Nov 21 at 20:11












  • Use Spring resource loading and use classpath:profiles/profile1.properties to load it.
    – M. Deinum
    Nov 21 at 20:25










  • @Denium the file names are unknown, I only know the the location of the profiles folder.
    – forhas
    Nov 21 at 20:31













up vote
0
down vote

favorite









up vote
0
down vote

favorite











In my spring-boot web app I have the following structure:



- resources
- properties
- profiles
- profile1.properties
- profile2.properties
- profile3.properties


I would like to read all the properties from all the files under the profiles folder. The solution should work for all of the following:




  • Running from an IDE

  • Running from a jar

  • Running on a windows server

  • Running on a linux server


I've encountered a few solution proposals but couldn't actually find one that works.










share|improve this question















In my spring-boot web app I have the following structure:



- resources
- properties
- profiles
- profile1.properties
- profile2.properties
- profile3.properties


I would like to read all the properties from all the files under the profiles folder. The solution should work for all of the following:




  • Running from an IDE

  • Running from a jar

  • Running on a windows server

  • Running on a linux server


I've encountered a few solution proposals but couldn't actually find one that works.







spring-boot executable-jar properties-file






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited yesterday

























asked Nov 21 at 20:07









forhas

4,991135187




4,991135187












  • Q: What "solution proposals"? Did they involve .getResourceAsStream()? What problem(s)/limitation(s) did you encounter?
    – paulsm4
    Nov 21 at 20:11












  • Use Spring resource loading and use classpath:profiles/profile1.properties to load it.
    – M. Deinum
    Nov 21 at 20:25










  • @Denium the file names are unknown, I only know the the location of the profiles folder.
    – forhas
    Nov 21 at 20:31


















  • Q: What "solution proposals"? Did they involve .getResourceAsStream()? What problem(s)/limitation(s) did you encounter?
    – paulsm4
    Nov 21 at 20:11












  • Use Spring resource loading and use classpath:profiles/profile1.properties to load it.
    – M. Deinum
    Nov 21 at 20:25










  • @Denium the file names are unknown, I only know the the location of the profiles folder.
    – forhas
    Nov 21 at 20:31
















Q: What "solution proposals"? Did they involve .getResourceAsStream()? What problem(s)/limitation(s) did you encounter?
– paulsm4
Nov 21 at 20:11






Q: What "solution proposals"? Did they involve .getResourceAsStream()? What problem(s)/limitation(s) did you encounter?
– paulsm4
Nov 21 at 20:11














Use Spring resource loading and use classpath:profiles/profile1.properties to load it.
– M. Deinum
Nov 21 at 20:25




Use Spring resource loading and use classpath:profiles/profile1.properties to load it.
– M. Deinum
Nov 21 at 20:25












@Denium the file names are unknown, I only know the the location of the profiles folder.
– forhas
Nov 21 at 20:31




@Denium the file names are unknown, I only know the the location of the profiles folder.
– forhas
Nov 21 at 20:31












1 Answer
1






active

oldest

votes

















up vote
-1
down vote



accepted










Based on a technical article written by Greg Briggs,
this is the solution I've written:



/**
* Loads all properties files under the given path, assuming it's under the classpath.
*
* @param clazz Any class that lives in the same place as the resources you want.
* @param parentFolderPath The profiles folder path, relative to the classpath.
* Should end with "/", but not start with one.
* Example: "properties/profiles/
* @return A set of all PropertyFile that represents all the properties files under the given path
* @throws IOException
*/
public static Set<PropertyFile> getPropertiesFromPath(Class<?> clazz, String parentFolderPath) throws IOException {
if (!parentFolderPath.endsWith("/")) {
throw new InvalidPathException(parentFolderPath, "Path must end with '/'");
}
Set<PropertyFile> retVal = Sets.newHashSet();
URL dirURL = clazz.getClassLoader().getResource(parentFolderPath);

if (dirURL != null && dirURL.getProtocol().equals("file")) { //IDE CASE
Resource profilesFolderResource = new ClassPathResource(parentFolderPath);
File profilesFolder = profilesFolderResource.getFile();
for (File propertiesFile : profilesFolder.listFiles()) {
Properties props = new Properties();
try (InputStream is = FileUtils.openInputStream(propertiesFile)) {
props.load(is);
PropertyFile propertyFile = new PropertyFile(propertiesFile.getName(), propertiesFile.getAbsolutePath(), props);
retVal.add(propertyFile);
}
}
return retVal;
} else if (dirURL.getProtocol().equals("jar")) { // A JAR PATH
String jarPath = getJarPathFromURL(dirURL); //strip out only the JAR file
JarFile jar = new JarFile(URLDecoder.decode(jarPath, Charsets.UTF_8.name()));
Enumeration<JarEntry> entries = jar.entries(); //gives ALL entries in jar
while (entries.hasMoreElements()) {
JarEntry jEntry = entries.nextElement();
String name = jEntry.getName();
if (isProfileFile(jEntry, parentFolderPath)) { //filter according to the path
Path pathOfFile = Paths.get(name);
String fileName = pathOfFile.toString().substring(pathOfFile.toString().lastIndexOf(File.separator) + 1);
Properties props = new Properties();
try (InputStream stream = jar.getInputStream(jEntry)) {
props.load(stream);
PropertyFile propertyFile = new PropertyFile(fileName, pathOfFile.toString(), props);
retVal.add(propertyFile);
}
}
}
return retVal;
}

throw new UnsupportedOperationException("Cannot list files for URL " + dirURL);
}

/**
* @param jarEntry
* @param parentFolderPath
* @return true if the file represented by the JarEntry
* is a properties file under the given parentFolderPath folder, else false
*/
private static boolean isProfileFile(JarEntry jarEntry, String parentFolderPath) {
boolean result = false;
String name = jarEntry.getName();
if (name.endsWith(PROPERTIES_SUFFIX)) {
Path pathOfFile = Paths.get(name);
Path pathOfParent = Paths.get(parentFolderPath);
String folderPath = pathOfFile.toString().substring(0, pathOfFile.toString().lastIndexOf(File.separator));
if (folderPath.endsWith(pathOfParent.toString())) {
result = true;
}
}
return result;
}

private static String getJarPathFromURL(URL dirURL) {
OSUtil.OS os = OSUtil.getOS();
//strip out only the JAR file
String jarPath = OSUtil.OS.WINDOWS == os ? dirURL.getPath().substring(6, dirURL.getPath().indexOf("!")) :
dirURL.getPath().substring(5, dirURL.getPath().indexOf("!"));
return jarPath;
}

public static class PropertyFile {

public String fileName;
public String filePath;
public Properties properties;

public PropertyFile(String fileName, String filePath, Properties properties) {
this.fileName = fileName;
this.filePath = filePath;
this.properties = properties;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof PropertyFile)) return false;
PropertyFile that = (PropertyFile) o;
return Objects.equals(filePath, that.filePath);
}

@Override
public int hashCode() {

return Objects.hash(filePath);
}

@Override
public String toString() {
return "PropertyFile{" +
"fileName='" + fileName + ''' +
", filePath='" + filePath + ''' +
", properties=" + properties +
'}';
}
}





share|improve this answer





















    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














     

    draft saved


    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53419749%2fread-files-from-a-nested-folder-in-a-jar%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    -1
    down vote



    accepted










    Based on a technical article written by Greg Briggs,
    this is the solution I've written:



    /**
    * Loads all properties files under the given path, assuming it's under the classpath.
    *
    * @param clazz Any class that lives in the same place as the resources you want.
    * @param parentFolderPath The profiles folder path, relative to the classpath.
    * Should end with "/", but not start with one.
    * Example: "properties/profiles/
    * @return A set of all PropertyFile that represents all the properties files under the given path
    * @throws IOException
    */
    public static Set<PropertyFile> getPropertiesFromPath(Class<?> clazz, String parentFolderPath) throws IOException {
    if (!parentFolderPath.endsWith("/")) {
    throw new InvalidPathException(parentFolderPath, "Path must end with '/'");
    }
    Set<PropertyFile> retVal = Sets.newHashSet();
    URL dirURL = clazz.getClassLoader().getResource(parentFolderPath);

    if (dirURL != null && dirURL.getProtocol().equals("file")) { //IDE CASE
    Resource profilesFolderResource = new ClassPathResource(parentFolderPath);
    File profilesFolder = profilesFolderResource.getFile();
    for (File propertiesFile : profilesFolder.listFiles()) {
    Properties props = new Properties();
    try (InputStream is = FileUtils.openInputStream(propertiesFile)) {
    props.load(is);
    PropertyFile propertyFile = new PropertyFile(propertiesFile.getName(), propertiesFile.getAbsolutePath(), props);
    retVal.add(propertyFile);
    }
    }
    return retVal;
    } else if (dirURL.getProtocol().equals("jar")) { // A JAR PATH
    String jarPath = getJarPathFromURL(dirURL); //strip out only the JAR file
    JarFile jar = new JarFile(URLDecoder.decode(jarPath, Charsets.UTF_8.name()));
    Enumeration<JarEntry> entries = jar.entries(); //gives ALL entries in jar
    while (entries.hasMoreElements()) {
    JarEntry jEntry = entries.nextElement();
    String name = jEntry.getName();
    if (isProfileFile(jEntry, parentFolderPath)) { //filter according to the path
    Path pathOfFile = Paths.get(name);
    String fileName = pathOfFile.toString().substring(pathOfFile.toString().lastIndexOf(File.separator) + 1);
    Properties props = new Properties();
    try (InputStream stream = jar.getInputStream(jEntry)) {
    props.load(stream);
    PropertyFile propertyFile = new PropertyFile(fileName, pathOfFile.toString(), props);
    retVal.add(propertyFile);
    }
    }
    }
    return retVal;
    }

    throw new UnsupportedOperationException("Cannot list files for URL " + dirURL);
    }

    /**
    * @param jarEntry
    * @param parentFolderPath
    * @return true if the file represented by the JarEntry
    * is a properties file under the given parentFolderPath folder, else false
    */
    private static boolean isProfileFile(JarEntry jarEntry, String parentFolderPath) {
    boolean result = false;
    String name = jarEntry.getName();
    if (name.endsWith(PROPERTIES_SUFFIX)) {
    Path pathOfFile = Paths.get(name);
    Path pathOfParent = Paths.get(parentFolderPath);
    String folderPath = pathOfFile.toString().substring(0, pathOfFile.toString().lastIndexOf(File.separator));
    if (folderPath.endsWith(pathOfParent.toString())) {
    result = true;
    }
    }
    return result;
    }

    private static String getJarPathFromURL(URL dirURL) {
    OSUtil.OS os = OSUtil.getOS();
    //strip out only the JAR file
    String jarPath = OSUtil.OS.WINDOWS == os ? dirURL.getPath().substring(6, dirURL.getPath().indexOf("!")) :
    dirURL.getPath().substring(5, dirURL.getPath().indexOf("!"));
    return jarPath;
    }

    public static class PropertyFile {

    public String fileName;
    public String filePath;
    public Properties properties;

    public PropertyFile(String fileName, String filePath, Properties properties) {
    this.fileName = fileName;
    this.filePath = filePath;
    this.properties = properties;
    }

    @Override
    public boolean equals(Object o) {
    if (this == o) return true;
    if (!(o instanceof PropertyFile)) return false;
    PropertyFile that = (PropertyFile) o;
    return Objects.equals(filePath, that.filePath);
    }

    @Override
    public int hashCode() {

    return Objects.hash(filePath);
    }

    @Override
    public String toString() {
    return "PropertyFile{" +
    "fileName='" + fileName + ''' +
    ", filePath='" + filePath + ''' +
    ", properties=" + properties +
    '}';
    }
    }





    share|improve this answer

























      up vote
      -1
      down vote



      accepted










      Based on a technical article written by Greg Briggs,
      this is the solution I've written:



      /**
      * Loads all properties files under the given path, assuming it's under the classpath.
      *
      * @param clazz Any class that lives in the same place as the resources you want.
      * @param parentFolderPath The profiles folder path, relative to the classpath.
      * Should end with "/", but not start with one.
      * Example: "properties/profiles/
      * @return A set of all PropertyFile that represents all the properties files under the given path
      * @throws IOException
      */
      public static Set<PropertyFile> getPropertiesFromPath(Class<?> clazz, String parentFolderPath) throws IOException {
      if (!parentFolderPath.endsWith("/")) {
      throw new InvalidPathException(parentFolderPath, "Path must end with '/'");
      }
      Set<PropertyFile> retVal = Sets.newHashSet();
      URL dirURL = clazz.getClassLoader().getResource(parentFolderPath);

      if (dirURL != null && dirURL.getProtocol().equals("file")) { //IDE CASE
      Resource profilesFolderResource = new ClassPathResource(parentFolderPath);
      File profilesFolder = profilesFolderResource.getFile();
      for (File propertiesFile : profilesFolder.listFiles()) {
      Properties props = new Properties();
      try (InputStream is = FileUtils.openInputStream(propertiesFile)) {
      props.load(is);
      PropertyFile propertyFile = new PropertyFile(propertiesFile.getName(), propertiesFile.getAbsolutePath(), props);
      retVal.add(propertyFile);
      }
      }
      return retVal;
      } else if (dirURL.getProtocol().equals("jar")) { // A JAR PATH
      String jarPath = getJarPathFromURL(dirURL); //strip out only the JAR file
      JarFile jar = new JarFile(URLDecoder.decode(jarPath, Charsets.UTF_8.name()));
      Enumeration<JarEntry> entries = jar.entries(); //gives ALL entries in jar
      while (entries.hasMoreElements()) {
      JarEntry jEntry = entries.nextElement();
      String name = jEntry.getName();
      if (isProfileFile(jEntry, parentFolderPath)) { //filter according to the path
      Path pathOfFile = Paths.get(name);
      String fileName = pathOfFile.toString().substring(pathOfFile.toString().lastIndexOf(File.separator) + 1);
      Properties props = new Properties();
      try (InputStream stream = jar.getInputStream(jEntry)) {
      props.load(stream);
      PropertyFile propertyFile = new PropertyFile(fileName, pathOfFile.toString(), props);
      retVal.add(propertyFile);
      }
      }
      }
      return retVal;
      }

      throw new UnsupportedOperationException("Cannot list files for URL " + dirURL);
      }

      /**
      * @param jarEntry
      * @param parentFolderPath
      * @return true if the file represented by the JarEntry
      * is a properties file under the given parentFolderPath folder, else false
      */
      private static boolean isProfileFile(JarEntry jarEntry, String parentFolderPath) {
      boolean result = false;
      String name = jarEntry.getName();
      if (name.endsWith(PROPERTIES_SUFFIX)) {
      Path pathOfFile = Paths.get(name);
      Path pathOfParent = Paths.get(parentFolderPath);
      String folderPath = pathOfFile.toString().substring(0, pathOfFile.toString().lastIndexOf(File.separator));
      if (folderPath.endsWith(pathOfParent.toString())) {
      result = true;
      }
      }
      return result;
      }

      private static String getJarPathFromURL(URL dirURL) {
      OSUtil.OS os = OSUtil.getOS();
      //strip out only the JAR file
      String jarPath = OSUtil.OS.WINDOWS == os ? dirURL.getPath().substring(6, dirURL.getPath().indexOf("!")) :
      dirURL.getPath().substring(5, dirURL.getPath().indexOf("!"));
      return jarPath;
      }

      public static class PropertyFile {

      public String fileName;
      public String filePath;
      public Properties properties;

      public PropertyFile(String fileName, String filePath, Properties properties) {
      this.fileName = fileName;
      this.filePath = filePath;
      this.properties = properties;
      }

      @Override
      public boolean equals(Object o) {
      if (this == o) return true;
      if (!(o instanceof PropertyFile)) return false;
      PropertyFile that = (PropertyFile) o;
      return Objects.equals(filePath, that.filePath);
      }

      @Override
      public int hashCode() {

      return Objects.hash(filePath);
      }

      @Override
      public String toString() {
      return "PropertyFile{" +
      "fileName='" + fileName + ''' +
      ", filePath='" + filePath + ''' +
      ", properties=" + properties +
      '}';
      }
      }





      share|improve this answer























        up vote
        -1
        down vote



        accepted







        up vote
        -1
        down vote



        accepted






        Based on a technical article written by Greg Briggs,
        this is the solution I've written:



        /**
        * Loads all properties files under the given path, assuming it's under the classpath.
        *
        * @param clazz Any class that lives in the same place as the resources you want.
        * @param parentFolderPath The profiles folder path, relative to the classpath.
        * Should end with "/", but not start with one.
        * Example: "properties/profiles/
        * @return A set of all PropertyFile that represents all the properties files under the given path
        * @throws IOException
        */
        public static Set<PropertyFile> getPropertiesFromPath(Class<?> clazz, String parentFolderPath) throws IOException {
        if (!parentFolderPath.endsWith("/")) {
        throw new InvalidPathException(parentFolderPath, "Path must end with '/'");
        }
        Set<PropertyFile> retVal = Sets.newHashSet();
        URL dirURL = clazz.getClassLoader().getResource(parentFolderPath);

        if (dirURL != null && dirURL.getProtocol().equals("file")) { //IDE CASE
        Resource profilesFolderResource = new ClassPathResource(parentFolderPath);
        File profilesFolder = profilesFolderResource.getFile();
        for (File propertiesFile : profilesFolder.listFiles()) {
        Properties props = new Properties();
        try (InputStream is = FileUtils.openInputStream(propertiesFile)) {
        props.load(is);
        PropertyFile propertyFile = new PropertyFile(propertiesFile.getName(), propertiesFile.getAbsolutePath(), props);
        retVal.add(propertyFile);
        }
        }
        return retVal;
        } else if (dirURL.getProtocol().equals("jar")) { // A JAR PATH
        String jarPath = getJarPathFromURL(dirURL); //strip out only the JAR file
        JarFile jar = new JarFile(URLDecoder.decode(jarPath, Charsets.UTF_8.name()));
        Enumeration<JarEntry> entries = jar.entries(); //gives ALL entries in jar
        while (entries.hasMoreElements()) {
        JarEntry jEntry = entries.nextElement();
        String name = jEntry.getName();
        if (isProfileFile(jEntry, parentFolderPath)) { //filter according to the path
        Path pathOfFile = Paths.get(name);
        String fileName = pathOfFile.toString().substring(pathOfFile.toString().lastIndexOf(File.separator) + 1);
        Properties props = new Properties();
        try (InputStream stream = jar.getInputStream(jEntry)) {
        props.load(stream);
        PropertyFile propertyFile = new PropertyFile(fileName, pathOfFile.toString(), props);
        retVal.add(propertyFile);
        }
        }
        }
        return retVal;
        }

        throw new UnsupportedOperationException("Cannot list files for URL " + dirURL);
        }

        /**
        * @param jarEntry
        * @param parentFolderPath
        * @return true if the file represented by the JarEntry
        * is a properties file under the given parentFolderPath folder, else false
        */
        private static boolean isProfileFile(JarEntry jarEntry, String parentFolderPath) {
        boolean result = false;
        String name = jarEntry.getName();
        if (name.endsWith(PROPERTIES_SUFFIX)) {
        Path pathOfFile = Paths.get(name);
        Path pathOfParent = Paths.get(parentFolderPath);
        String folderPath = pathOfFile.toString().substring(0, pathOfFile.toString().lastIndexOf(File.separator));
        if (folderPath.endsWith(pathOfParent.toString())) {
        result = true;
        }
        }
        return result;
        }

        private static String getJarPathFromURL(URL dirURL) {
        OSUtil.OS os = OSUtil.getOS();
        //strip out only the JAR file
        String jarPath = OSUtil.OS.WINDOWS == os ? dirURL.getPath().substring(6, dirURL.getPath().indexOf("!")) :
        dirURL.getPath().substring(5, dirURL.getPath().indexOf("!"));
        return jarPath;
        }

        public static class PropertyFile {

        public String fileName;
        public String filePath;
        public Properties properties;

        public PropertyFile(String fileName, String filePath, Properties properties) {
        this.fileName = fileName;
        this.filePath = filePath;
        this.properties = properties;
        }

        @Override
        public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof PropertyFile)) return false;
        PropertyFile that = (PropertyFile) o;
        return Objects.equals(filePath, that.filePath);
        }

        @Override
        public int hashCode() {

        return Objects.hash(filePath);
        }

        @Override
        public String toString() {
        return "PropertyFile{" +
        "fileName='" + fileName + ''' +
        ", filePath='" + filePath + ''' +
        ", properties=" + properties +
        '}';
        }
        }





        share|improve this answer












        Based on a technical article written by Greg Briggs,
        this is the solution I've written:



        /**
        * Loads all properties files under the given path, assuming it's under the classpath.
        *
        * @param clazz Any class that lives in the same place as the resources you want.
        * @param parentFolderPath The profiles folder path, relative to the classpath.
        * Should end with "/", but not start with one.
        * Example: "properties/profiles/
        * @return A set of all PropertyFile that represents all the properties files under the given path
        * @throws IOException
        */
        public static Set<PropertyFile> getPropertiesFromPath(Class<?> clazz, String parentFolderPath) throws IOException {
        if (!parentFolderPath.endsWith("/")) {
        throw new InvalidPathException(parentFolderPath, "Path must end with '/'");
        }
        Set<PropertyFile> retVal = Sets.newHashSet();
        URL dirURL = clazz.getClassLoader().getResource(parentFolderPath);

        if (dirURL != null && dirURL.getProtocol().equals("file")) { //IDE CASE
        Resource profilesFolderResource = new ClassPathResource(parentFolderPath);
        File profilesFolder = profilesFolderResource.getFile();
        for (File propertiesFile : profilesFolder.listFiles()) {
        Properties props = new Properties();
        try (InputStream is = FileUtils.openInputStream(propertiesFile)) {
        props.load(is);
        PropertyFile propertyFile = new PropertyFile(propertiesFile.getName(), propertiesFile.getAbsolutePath(), props);
        retVal.add(propertyFile);
        }
        }
        return retVal;
        } else if (dirURL.getProtocol().equals("jar")) { // A JAR PATH
        String jarPath = getJarPathFromURL(dirURL); //strip out only the JAR file
        JarFile jar = new JarFile(URLDecoder.decode(jarPath, Charsets.UTF_8.name()));
        Enumeration<JarEntry> entries = jar.entries(); //gives ALL entries in jar
        while (entries.hasMoreElements()) {
        JarEntry jEntry = entries.nextElement();
        String name = jEntry.getName();
        if (isProfileFile(jEntry, parentFolderPath)) { //filter according to the path
        Path pathOfFile = Paths.get(name);
        String fileName = pathOfFile.toString().substring(pathOfFile.toString().lastIndexOf(File.separator) + 1);
        Properties props = new Properties();
        try (InputStream stream = jar.getInputStream(jEntry)) {
        props.load(stream);
        PropertyFile propertyFile = new PropertyFile(fileName, pathOfFile.toString(), props);
        retVal.add(propertyFile);
        }
        }
        }
        return retVal;
        }

        throw new UnsupportedOperationException("Cannot list files for URL " + dirURL);
        }

        /**
        * @param jarEntry
        * @param parentFolderPath
        * @return true if the file represented by the JarEntry
        * is a properties file under the given parentFolderPath folder, else false
        */
        private static boolean isProfileFile(JarEntry jarEntry, String parentFolderPath) {
        boolean result = false;
        String name = jarEntry.getName();
        if (name.endsWith(PROPERTIES_SUFFIX)) {
        Path pathOfFile = Paths.get(name);
        Path pathOfParent = Paths.get(parentFolderPath);
        String folderPath = pathOfFile.toString().substring(0, pathOfFile.toString().lastIndexOf(File.separator));
        if (folderPath.endsWith(pathOfParent.toString())) {
        result = true;
        }
        }
        return result;
        }

        private static String getJarPathFromURL(URL dirURL) {
        OSUtil.OS os = OSUtil.getOS();
        //strip out only the JAR file
        String jarPath = OSUtil.OS.WINDOWS == os ? dirURL.getPath().substring(6, dirURL.getPath().indexOf("!")) :
        dirURL.getPath().substring(5, dirURL.getPath().indexOf("!"));
        return jarPath;
        }

        public static class PropertyFile {

        public String fileName;
        public String filePath;
        public Properties properties;

        public PropertyFile(String fileName, String filePath, Properties properties) {
        this.fileName = fileName;
        this.filePath = filePath;
        this.properties = properties;
        }

        @Override
        public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof PropertyFile)) return false;
        PropertyFile that = (PropertyFile) o;
        return Objects.equals(filePath, that.filePath);
        }

        @Override
        public int hashCode() {

        return Objects.hash(filePath);
        }

        @Override
        public String toString() {
        return "PropertyFile{" +
        "fileName='" + fileName + ''' +
        ", filePath='" + filePath + ''' +
        ", properties=" + properties +
        '}';
        }
        }






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 22 at 17:33









        forhas

        4,991135187




        4,991135187






























             

            draft saved


            draft discarded



















































             


            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53419749%2fread-files-from-a-nested-folder-in-a-jar%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            What visual should I use to simply compare current year value vs last year in Power BI desktop

            How to ignore python UserWarning in pytest?

            Alexandru Averescu