code: package org.rug.data.characteristics.comps;
  
  import org.apache.tinkerpop.gremlin.structure.Vertex;
  import org.rug.data.labels.VertexLabel;
  import org.slf4j.Logger;
  import org.slf4j.LoggerFactory;
  
  import java.io.File;
  import java.nio.file.Path;
  import java.util.Optional;
  
  /**
   * Retrieves source code of Java classes from Java projects.
   */
  public class JavaSourceCodeRetriever extends SourceCodeRetriever {
  
      private final static Logger logger = LoggerFactory.getLogger(JavaSourceCodeRetriever.class);
  
      /**
       * Instantiates a retriever for Java projects.
       * @param sourcePath the path to the directory which children are the packages of the Java classes.
       */
      public JavaSourceCodeRetriever(Path sourcePath) {
          super(sourcePath);
      }
  
      /**
       * Transforms element from a full name description (e.g. org.package.Class) to a file name path (e.g. org/package/Class.java).
       * This method removes inner classes and returns the files were they are defined.
       * @param element the element to extract the file path from.
       * @return a string that represents the name of the file defining the class and the packages containing
       * such class.
       */
      @Override
      protected String toFileName(Vertex element) {
          String elementName = element.value("name");
          String extension;
          switch (VertexLabel.fromString(element.label())){
              case CLASS:
                  extension = ".java";
                  break;
              default:
                  extension = "";
                  break;
          }
          return toFileName(elementName, extension);
      }
  
      /**
       * Converts the dotted name of the given element to a concrete file name with the .java extension.
       * @param elementName the name of the element to convert.
       * @return a path suffix of the given element.
       */
      @Override
      protected String toFileName(String elementName, String extension){
          return clean(elementName).replace('.', File.separatorChar) + extension;
      }
  
      @Override
      public Optional<Path> getPathOf(Vertex component) {
          var tryFullName = super.getPathOf(component);
          if (tryFullName.isEmpty()) {
              try {
                  String compName = component.value("name");
                  compName = compName.substring(compName.lastIndexOf(".") + 1);
                  return super.getPathOf(compName, ".java");
              }catch (Exception e){
                  return tryFullName;
              }
          }
          return tryFullName;
      }
  
      /**
       * Removes internal classes and lambdas from and extracts the file name without extension.
       * @param elementName the elementName to clean.
       * @return a cleaned element name string.
       */
      private String clean(String elementName) {
          if (elementName.contains("$")) {
              elementName = elementName.substring(0, elementName.indexOf("$"));
          }
          return elementName;
      }
  }
  