views:

60

answers:

1

I need to search through a list of folders that could have more folders inside it, and add a new folder depending what folder is its parent.(the path is stored as a String for eg = "root/MyCom/home/") Then i fill in a field with a new folder name and add it to the final folder(eg "home/").

Below as you can see , I can navigate to the right location and add the new folder to a current folder, My trouble is that i cannot ensure that currentFolder element is placed back in the list it came from

how could i add a folder to a list of folders, that could be within a list of folders,that could be within a list of folders and endless more?

      YFUser user = (YFUser)getSession().getAttribute(SESSION_USER);

      Folder newFolder = new Folder();
      newFolder.setFolderName(foldername);

              // this is the path string (root/MyCom/home/) split in the different folder names

      String folderNames[] = folderLocationString.split("/");
      int folderNamesLength = folderNames.length;

      Folder root = user.getRoot();

      Folder currentFolder = root;

      for(int i=0;i<folderNamesLength; i++){
         // because root is folderNames[i]

          String folderName = folderNames[i];

          int currentFolderSize = currentFolder.getChildren.getSize();

          for(int o=1; o<= currentFolderSize ; o++){

              if(currentFolder.getChildren().get(o) instanceof Folder){
                if(folderName.equals(currentFolder.getChildren().get(o).getFolderName())){

                    currentFolder = currentFolder.getChildren().get(o);

                    if  (i == counter){
//now i am inside the correct folder and i add it to the list of folders within it
//the trouble is knowing how to re add this changed folder back to the list before it

                        currentFolder.getChildren.add(newFolder);
                    }

                }
              }
          }

      }

this is a simple version of what i need to do

public class Main {

/**
 * @param args
 */
public static void main(String[] args) {

    List<String> strings = new ArrayList<String>();

    strings.add("Donkey");
    strings.add("hello");
    strings.add("me");
    strings.add("you");
    strings.add("everyone");
    strings.add("not u");

    int counter= strings.size();

    for (int i=0 ; i< counter ; i++){
        System.out.println(strings.get(i));
        if(strings.get(i).equals("Donkey")){
            strings.remove(i);
            strings.add(i, "not a Donkey");
        }
    }

    for(String s : strings){
        System.out.println(s);
    }
    }
}

this will print out Donkey, hello, me, you, everyone, not u

and then

not a Donkey, hello, me, you, everyone, not u,

as you can see here i am replacing the "Donkey" string with "not a Donkey"

so in terms of my project, i need to get the parent folder from the list, add the new Folder and then remove the old parent folder with the new updated one.

edit:

this is my folder class that holds a list of hierarchy objects, which can be either fileInformations or Folders,`

package com.example.client;

@Entity
@DiscriminatorValue("F")
public class Folder extends Hierarchy   {

@OneToMany(cascade = CascadeType.ALL,fetch = FetchType.EAGER)
@JoinTable(name = "FOLDER_JOIN_FILELOCATION", joinColumns = { 
        @JoinColumn(name = "folder_id") }, inverseJoinColumns = { 
        @JoinColumn(name = "file_information_id") })
private List<Hierarchy> children = new ArrayList<Hierarchy>() ;
@Column(name = "folder_name")
private String folderName;
@ManyToOne( cascade = {CascadeType.PERSIST, CascadeType.MERGE} )
   @JoinTable(name="FOLDER_JOIN_FOLDER",
        joinColumns = @JoinColumn(name="parent_folder_id"),
        inverseJoinColumns = @JoinColumn(name="folder_ID")
    ) 
private Hierarchy parent;



public Folder(){

}

public String getFolderName() {
    return folderName;
}

public void setFolderName(String folderName) {
    this.folderName = folderName;
}

public List<Hierarchy> getChildren() {
    return children;
}

public void setChildren(List<Hierarchy> children) {
    this.children = children;
}




@Override
public void addChild(Hierarchy h) {
    children.add(h);        
}



public Hierarchy getParent() {
    return parent;
}

public void setFolder(Hierarchy folder) {
    this.parent = folder;
}

@Override
public String toString() {
    String val = this.folderName;
    val += "/";
    for(Hierarchy h : children ){

        val += h.toString();

    }

    return val;


}


public Hierarchy getChild(int index){
    return children.get(index);
}

 }

now this example below, when i take out an element of the list, edit it , i think peter is saying that this will edit the list directly, but when i run this code it does not

    List<String> strings = new ArrayList<String>();

    strings.add("Donkey");
    strings.add("hello");
    strings.add("me");
    strings.add("you");
    strings.add("everyone");
    strings.add("not u");

    int counter= strings.size();


for (int i=0 ; i< counter ; i++){
        System.out.println(strings.get(i));
        if(strings.get(i).equals("Donkey")){
            String test = strings.get(i);
            test += " not now though";
        }
    }

    for(String s : strings){
        System.out.println(s);
    }

`

A: 

I am not sure if understand your problem correctly. You say

My trouble is that i cannot ensure that currentFolder element is placed back in the list it came from

However, my understanding is that currentFolder is already inside the list, and simply changing the state of currentFolder is not affecting this fact. In all list implementations I know, a call to get() just returns a reference to an element in the list, without removing that element. Unless you explicitly remove currentFolder from its containing list, it is going it stay there.

Anyway, in general, the solution to similar problems is to keep a reference to the parent of the current folder:

  Folder currentFolder = root;
  Folder parentFolder = null;

  for(int i=0;i<folderNamesLength; i++){
     // because root is folderNames[i]

      String folderName = folderNames[i];

      int currentFolderSize = currentFolder.getChildren.getSize();

      for(int o=1; o<currentFolderSize ; o++){

          if(currentFolder.getChildren().get(o) instanceof Folder){
            Folder childFolder = currentFolder.getChildren().get(o);

            if(folderName.equals(childFolder.getFolderName())){
                parentFolder = currentFolder;
                currentFolder = childFolder;

                if  (i == counter){
                    currentFolder.getChildren.add(newFolder);
                    // reorganize parentFolder.getChildren() or whatever
                }

            }
          }
      }

  }

One side note: in your outer loop

for(int i=0;i<=folderNamesLength; i++){

you go one too far - the condition should be

for(int i=0;i<folderNamesLength; i++){

Same applies for the inner loop.

Moreover you are incrementing i both above and inside the loop:

String folderName = folderNames[i++];

should be

String folderName = folderNames[i];
Péter Török
ok so i changed them peter, but that is not what i am getting at, what i want is to be able to add the folder to the final folder on the string path and ensure that the effects are felt through out the all the lists effected.
molleman
@molleman, see my update.
Péter Török
@Péter Török yes peter but when i reorganize the parent folder, this just @peter affects the parent folder local variable and not the parent folder entity itself within the list. i know i get a reference to the folder with get(0)(if i edit this reference it does not edit the one within the list), i have put up a simple version of what i need
molleman
@molleman, AFAIU the only way this is possible is if either `getChildren()` or `get()` returns a _copy_ of, instead of a reference to the original. Please clarify which case it is (preferably by publishing the relevant code bits from `Folder` and - if applicable - from the `children` collection).
Péter Török
@Péter Török i placed up my code for folder in my update
molleman
@molleman, you are talking about a _table in a DB_, mapped with JPA! Man, it took some struggle to get this key piece of info out of you... So you want the changes in the local entity updated in the DB as well, right? Assuming the user and its root folder is already persisted, since you have `cascade = CascadeType.ALL`, I don't think you need to do anything special except maybe calling `entityManager.flush()` to force the synchronization of changes in the whole object graph to the DB.
Péter Török
@Péter Török , if i want to update the Hierarchy list , i just call the hibernate session.update(user);but i want to add the new folder to an existing folder and then update the list within my YFUser entity. when i take out a folder from the and it is a folder that matches the path, then go within this folder and search for the next folder on the path(and so on and so forth), but this logic will not allow me when i find the final folder to add the new folder to it, thus i cannot update my database, as the folder has not been addedand then call hibernate session.update(user);
molleman
@molleman, sorry, but I just don't get it. You DO add the folder to the list of children in `currentFolder.getChildren.add(newFolder)`. That list of children IS part of the folder hierarchy, since `Folder.getChildren()` returns a reference to the original, NOT a copy. Same applies to `getChildren().get()`. I feel there is some fundamental misunderstanding here, but I can't put my finger on it.
Péter Török
@Péter Török , i updated my post
molleman
i updated my post above with a simple example of what might explain my problem
molleman
@molleman, the fundamental difference between `String` and `Folder` is that former is _immutable_. I.e. in `String test = strings.get(i); test += " not now though";` the `+=` operator can't modify the original string, so it implicitly creates a new string and returns that. I.e. after this, `test != strings.get(i)`! However, after executing `currentFolder.getChildren.add(newFolder);`, `currentFolder` still refers to the same physical object which is stored in the list, i.e. `currentFolder == parentFolder.getChildren().get(o)`. You don't need to believe this to me - check it in a debugger.
Péter Török
now peter i just was getting a little confused, cheers for clarifying this for me , u helped me out alot, thank you for the answer.
molleman