# methode ruft sich selbst auf



## tanzverfuehrung (20. Apr 2011)

also meine methode node soll mir immer den letzten knoten des pfades ausgeben!!!

ich glaube langsam bin ich auch von einen guten weg!
jedoch kann mir jemand weiter helfen...
und zwar mein problem!
wenn ich den ersten ELtern knoten erzeugen will!ruft die methode sich selbst auf!
ABER mein problem das es wie eine endlos schleife ist!
man kommt einfach nicht weiter aber ich weiß auch nciht wie ich es anders umsetzten soll!

Preferences parentNode = value.node(path[0]); 

das ist mal die ganze node methode von mir!


```
@Override
	public org.osgi.service.prefs.Preferences node(String pathName) {

		SimplePreferences value = nodeMap.get(pathName); // prüfen ob pfad
															// vorhanden ist
		String[] path = pathName.split("/"); // Pfad splitten
		Preferences childNode = null;

		if (value == null) { // pfad nicht vorhanden
			value = new SimplePreferences(path[0]); // knoten erzeugen
			nodeMap.put(path[0], value);
			return value;
		}
		if (value != null) { // pfad vorhanden
			Preferences parentNode = value.node(path[0]); // erste
															// Knoten(eltern)
															// erzeugen
			for (int i = 1; i < path.length; i++) {
				childNode = parentNode.node(path[i]);
				parentNode = childNode;
			}
		}
		return childNode;
	}
```


----------



## faetzminator (20. Apr 2011)

Wo hast du hier eine Rekursion? Wie heisst die Klasse der geposteten Methode? Wo kriegst du deiner Ansicht nach eine Endlosschleife?


----------



## tanzverfuehrung (20. Apr 2011)

faetzminator hat gesagt.:


> Wo hast du hier eine Rekursion? Wie heisst die Klasse der geposteten Methode? Wo kriegst du deiner Ansicht nach eine Endlosschleife?



brauche ich unbedingt eine rekursion?

ok habe mir grad nochmal rekursion angeguckt!und jetzt verstehe ich!man braucht es wenn sich eine methode selbst aufrufen soll...ODER?

Klasse heißt 
public class SimplePreferences implements org.osgi.service.prefs.Preferences 

und wenn ich es im debug modus durch laufen lasse
wiederholt sich vorgang immer wieder

wenn er dahoin kommt:
(Zeile15)
	Preferences parentNode = value.node(path[0]); 

springt er gleich wieder zu
(Zeile 4)
SimplePreferences value = nodeMap.get(pathName); // prüfen ob pfad
															// vorhanden ist
		String[] path = pathName.split("/"); // Pfad splitten
		Preferences childNode = null;



und das wird dann immer wieder wiederholt!


----------



## SlaterB (20. Apr 2011)

ein weiteres Posting zu 
http://www.java-forum.org/allgemeine-java-themen/116758-osgi-preferences-letzter-pathname.html
hab schon zwei neue Themen dorthin eingefügt,
jetzt lasse ich es hier mal getrennt, ist ja auch grenzwertiges Thema zwischen einfacher Rekursion und OSGI-Spezialitäten

node() wird rekursiv aufgerufen, prüfe doch ob path[0] dem gesamten übergebenen pathName gleicht (equals), ob das path-Array die Länge 1 hat,
widerspricht ein wenig dem Code von Zeile 10-13, aber wie sonst soll es zur Rekursion kommen?
gibt mit System.out.println() alle Informationen aus

was du in Fall der Gleichheit anders machen musst ist vielleicht noch nicht direkt klar, 
auf jeden Fall macht wiederholte Ausführung dann keinen Sinn


----------



## Tomate_Salat (20. Apr 2011)

tanzverfuehrung hat gesagt.:


> ok habe mir grad nochmal rekursion angeguckt!und jetzt verstehe ich!man braucht es wenn sich eine methode selbst aufrufen soll...ODER?



Hell auf hell ist keine gute Idee: es ist anstrengend zu lesen und tut auch in den Augen weh. Wenn du etwas hervorheben willst (wenn es den sein muss) nimm bitte in Zukunft eine Farbe, die man angenehmer lesen kann ;-)


----------



## akimoon (20. Apr 2011)

tanzverfuehrung hat gesagt.:


> brauche ich unbedingt eine rekursion?
> 
> ok habe mir grad nochmal rekursion angeguckt!und jetzt verstehe ich!man braucht es wenn sich eine methode selbst aufrufen soll...ODER?



Ich stimme dem Salat ausnahmsweise mal zu... die Farbe ist nicht wirklich angenehm für die Augen :autsch:

Rekursion bedeutet nichts anderes, als dass sich eine Methode selbst wieder aufruft.


----------



## tanzverfuehrung (20. Apr 2011)

SlaterB hat gesagt.:


> node() wird rekursiv aufgerufen, prüfe doch ob path[0] dem gesamten übergebenen pathName gleicht (equals), ob das path-Array die Länge 1 hat,
> widerspricht ein wenig dem Code von Zeile 10-13, aber wie sonst soll es zur Rekursion kommen?
> gibt mit System.out.println() alle Informationen aus
> 
> ...



ich habe nochmal alles überarbeitet!
und habe jetzt zwei methoden
die eine methode getNode, die guckt ob es ein pfade gibt oder erzeugt!
und die klasse node,die den letzen knoten ausgeben soll!
aber so ganz funtioniert das nicht nicht!
kannn mir jemand sagen wieso???
???:L
es funktioniert für absoluten pfad nicht und für relativen auch nicht!
aber für eins muss es doch funktionieren und eigentlich sogar für beide oder?

eigentlich soll ich die beiden fälle dann nämlich auch noch unterscheiden!
:bahnhof:


```
@Override
	public org.osgi.service.prefs.Preferences node(String pathName) {
		
		  int index = getNode(pathName).toString().indexOf("/");
		
		  if (index<0) //Wenn der index < 0 ist wurde kein Slash mehr gefunden und im pathName steht das letzte Element
		        return this;
		  
		   //Wenn der Index >=0 wurde ein Slash gefunden
		    pathName = pathName.substring(++index); // Der Anfang des Strings bis zum gefundenen Slash wird abgeschnitten
		    return node(pathName); //die Methode ruft sich selbst mit dem gekürzten pathName auf
		}
	


	/**
	 * Prüft ob ein Pfad vorhanden ist, wenn kein pfad vorhanden ist, erzeuge
	 * ihn und gebe ihn zurück!
	 * 
	 * @param
	 * @return value, der gegebene oder erzeugte Pfad
	 */
	public org.osgi.service.prefs.Preferences getNode(String pathName) {

		SimplePreferences value = nodeMap.get(pathName); // prüfen ob pfad
															// vorhanden ist

		if (value == null) { // pfad nicht vorhanden
			value = new SimplePreferences(pathName); // knoten erzeugen
			nodeMap.put(pathName, value);
		}
		return value;
	}
```






SlaterB hat gesagt.:


> ein weiteres Posting zu
> http://www.java-forum.org/allgemeine-java-themen/116758-osgi-preferences-letzter-pathname.html
> hab schon zwei neue Themen dorthin eingefügt,
> jetzt lasse ich es hier mal getrennt, ist ja auch grenzwertiges Thema zwischen einfacher Rekursion und OSGI-Spezialitäten



ja tut mir leid,aber hatte ja jetzt auch ne ganz andere frAGE,deswegen dachte ich,ich kann neues thema´eröffnen!


----------



## SlaterB (20. Apr 2011)

wie zuvor sicherlich auch schon geschrieben wurde, aber ich kann mich ja auch versuchen:
gib Informationen, Informationen, Informationen

wo ist z.B. die Methode node() implementiert, in welcher Klasse?
angenommen es wird ein einfacher Pfad "x" übergeben, dann dürfte von node() aus getNode() ein SimplePreferences-Objekt A zurückgeben,
mit index < 0 wieder in node(), 

aber node() gibt dann nicht dieses Objekt A zurück, sondern sich selber, this, 
was ist in dieser Situation richtig, müsste nicht das SimplePreferences-Objekt A zurückgegeben werden?
was ist this, welche Klasse, auch SimplePreferences?

durch den rekursiven Aufruf wird ein evtl. doch längerer Path verkürzt, durch weitere getNode()-Aufrufe die Map möglicherweise um weitere Einträge erweitert, am Ende wird aber aber immer garantiert this zurückgegeben (oder Endlosschleife), ein anderes return gibt es in der Methode node() gar nicht,
was immer das Objekt ist an dem node() aufgerufen wird, dieses wird garantiert auch zurückgegeben,

bringt dich diese Erkenntnis weiter?


----------



## tanzverfuehrung (20. Apr 2011)

SlaterB hat gesagt.:


> bringt dich diese Erkenntnis weiter?




erlich gesagt NEIN!bin jetzt richtig verwirrt



SlaterB hat gesagt.:


> wie zuvor sicherlich auch schon geschrieben wurde, aber ich kann mich ja auch versuchen:
> gib Informationen, Informationen, Informationen
> 
> wo ist z.B. die Methode node() implementiert, in welcher Klasse?
> ...


public class SimplePreferences implements org.osgi.service.prefs.Preferences 

ja also die methode node() ist in preferences implemtiert



> aber node() gibt dann nicht dieses Objekt A zurück, sondern sich selber, this,
> was ist in dieser Situation richtig, müsste nicht das SimplePreferences-Objekt A zurückgegeben werden?
> was ist this, welche Klasse, auch SimplePreferences?



ich dachte this ist der pathName

also eigentlich müpsste ja bei der return aussage
return pathName stehen!
bloß wie tue ich das?
weil pathNAme ist ein String aber es soll ein Preferences zurück gegeben werden?????
:bahnhof:




SlaterB hat gesagt.:


> durch den rekursiven Aufruf wird ein evtl. doch längerer Path verkürzt, durch weitere getNode()-Aufrufe die Map möglicherweise um weitere Einträge erweitert, am Ende wird aber aber immer garantiert this zurückgegeben (oder Endlosschleife), ein anderes return gibt es in der Methode node() gar nicht,
> was immer das Objekt ist an dem node() aufgerufen wird, dieses wird garantiert auch zurückgegeben,


;(






es tut mir leid aber ich weiß nicht wie ich das alle besser formulieren soll!


----------



## SlaterB (20. Apr 2011)

bei soviel Text bereits helfen Erklärkungen kaum mehr, vielleicht dieses Programm?:


```
public class Test {
    public static void main(String[] args) {
        IKnowManyPrefs x = new IKnowManyPrefs();
        Pref a = x.node("test/tes/te/t");
        System.out.println(a);
    }
}

class IKnowManyPrefs { // ist selber nicht unbedingt Pref
    Map<String, SimplePref> nodeMap = new HashMap<String, SimplePref>();

    public Pref node(String pathName)  {
        Pref p = getNode(pathName);
        int index = p.toString().indexOf("/");

        if (index < 0)  {
            // nicht this zurückgeben, this ist Müll
            return p;
        }

        pathName = pathName.substring(++index);
        return node(pathName); // Rekursion
    }

    public Pref getNode(String pathName)  {
        SimplePref value = nodeMap.get(pathName);
        if (value == null)    {
            System.out.println("lege Node an für Path: " + pathName);
            value = new SimplePref(pathName);
            nodeMap.put(pathName, value);
        }
        return value;
    }
}

class SimplePref  implements Pref {
    private String path;

    public SimplePref(String path) {
        this.path = path;
    }

    public String toString()    {
        return this.path;
    }

}

interface Pref {}
```
Ausgabe:

```
lege Node an für Path: test/tes/te/t
lege Node an für Path: tes/te/t
lege Node an für Path: te/t
lege Node an für Path: t
t
```


----------



## Landei (20. Apr 2011)

Zum Verständnis der Rekursion nehmen wir ein ganz einfaches Beispiel, die Fakultäts-Funktion:

Zuerst die gewohnte iterative Variante, die fac(n) = 1*2*3*...*n in einer Schleife berechnet:

```
public int fac(int n) {
   int f = 1;
   for(int i = 1; i <= n; i++) {
     f = f * i;
   }
   return f;
}
```

Nun kann man fac(n) auch so definieren, dass man fac(0) = 1 setzt (das ist der "Basisfall"), und dass fac(n) = n*fac(n-1) ist (das ist der "Rekursionsschritt").  Dass letztere Formel stimmt, wird klar, wenn man einen Wert einsetzt, z.B. n = 5. Dann ist nach der ursprünglichen Definition fac(5) = 1*2*3*4*5, und nach der rekursiven Definition fac(5) = 5*fac(4) = 5 * (1*2*3*4) = 1*2*3*4*5. Natürlich kann auch fac(4) wieder rekursiv berechnet werden. Und fac(3). Und fac(2). Und fac(1). Aber fac(0) *nicht*, dafür haben wir ja unseren speziellen Basisfall. Deshalb hört die Rekursion auch irgendwann auf (wenn sie richtig geschrieben ist).

Das ganze in Java:


```
public int fac(int n) {
   if (n == 0) {
      return 1;
   } else {
      return n * fac(n-1);
   } 
}
```


----------



## tanzverfuehrung (20. Apr 2011)

SlaterB hat gesagt.:


> ....



also danke für das gut beispiel erstmal!
hat mir schon wieder weiter geholfen aber gehen tut es trotzdem nicht1
verstehe ich nicht!

ich gebe mal am besten die ganze klasse.evntuell findest du oder jemand anderes ja mein fehler


```
import java.text.ParsePosition;
import java.util.HashMap;
import java.util.Map;

import javax.xml.soap.Node;

import org.junit.rules.TemporaryFolder;
import org.osgi.service.prefs.BackingStoreException;
import org.osgi.service.prefs.Preferences;
import org.w3c.dom.NodeList;

/**
 * 
 * @author Christin
 * 
 * 
 */
public class SimplePreferences implements org.osgi.service.prefs.Preferences {
	/**
	 * map wird mit String & Int Werten & mit dem dazugehörigen passendem
	 * Schlüssel gefüllt
	 */
	Map<String, Object> hashMap = new HashMap<String, Object>();
	/**
	 * nodeMap wird mit den PfadNAmen & mit dem dazugehörigen passendem
	 * Schlüssel gefüllt
	 */
	Map<String, SimplePreferences> nodeMap = new HashMap<String, SimplePreferences>();

	private String name;

	/**
	 * Erzeugt Knoten mit entsprechendem Namen
	 * 
	 * @param name
	 */
	public SimplePreferences(String name) {
		super();
		this.name = name;
	}

	/**
	 * Methode packt den String Schlüssel & die String Wert in die Pereference
	 * und in die {@link SimplePreferences#hashMap}
	 * 
	 * @param key
	 *            Schlüssel
	 * @param value
	 *            Wert
	 */
	@Override
	public void put(String key, String value) {
		hashMap.put(key, value);
	}

	/**
	 * Methode überprüft ob in der {@link SimplePreferences#hashMap} zu dem
	 * String Schlüssel ein passender String Wert existiert
	 * 
	 * @param key
	 *            Schlüssel in der Preference
	 * @param defaultValue
	 *            Standertwert zu dem zugehörigen Schlüssel
	 * @return <li>defaultValue ,wenn die {@link SimplePreferences#hashMap} kein
	 *         Wert enthält. <li>value.toString ,der enthaltene Wert in der
	 *         {@link SimplePreferences#hashMap}
	 */
	@Override
	public String get(String key, String defaultValue) {
		Object value = hashMap.get(key);
		if (value == null)
			return defaultValue;
		return value.toString();
	}

	/**
	 * Methode packt den String Schlüssel & den Int Wert in die Pereference und
	 * in die {@link SimplePreferences#hashMap}
	 * 
	 * @param key
	 *            Schlüssel
	 * @param value
	 *            Wert
	 */
	@Override
	public void putInt(String key, int value) {
		hashMap.put(key, value);
	}

	/**
	 * Methode überprüft ob in der {@link SimplePreferences#hashMap} zu dem
	 * String Schlüssel ein passender Int Wert existiert
	 * 
	 * @param key
	 *            Schlüssel in der Preference
	 * @param defaultValue
	 *            Standertwert zu dem zugehörigen Schlüssel
	 * @return<li>value ,der enthaltene Wert in der
	 *                  {@link SimplePreferences#hashMap} <li>defaultValue ,wenn
	 *                  ein {@link NumberFormatException} ausgelöst wird
	 */
	@Override
	public int getInt(String key, int defaultValue) {
		String value = get(key, "" + defaultValue);
		try {
			return Integer.parseInt(value);
		} catch (NumberFormatException e) {
			return defaultValue;
		}
	}

	@Override
	public org.osgi.service.prefs.Preferences node(String pathName) {
			
		Preferences p = getNode( pathName);
		  int index = p.toString().indexOf("/");
		
			 if (pathName == "") 
			 return this;

		  if (index<0) //Wenn der index < 0 ist wurde kein Slash mehr gefunden und im pathName steht das letzte Element
		        return p;
		  
		   //Wenn der Index >=0 wurde ein Slash gefunden
		    pathName = pathName.substring(++index); // Der Anfang des Strings bis zum gefundenen Slash wird abgeschnitten
		    return node(pathName); //die Methode ruft sich selbst mit dem gekürzten pathName auf
		}
	


	/**
	 * Prüft ob ein Pfad vorhanden ist, wenn kein pfad vorhanden ist, erzeuge
	 * ihn und gebe ihn zurück!
	 * 
	 * @param
	 * @return value, der gegebene oder erzeugte Pfad
	 */
	public org.osgi.service.prefs.Preferences getNode(String pathName) {

		SimplePreferences value = nodeMap.get(pathName); // prüfen ob pfad
															// vorhanden ist

		if (value == null) { // pfad nicht vorhanden
			value = new SimplePreferences(pathName); // knoten erzeugen
			nodeMap.put(pathName, value);
		}
		return value;
	}

	@Override
	public String[] childrenNames() {
		throw new UnsupportedOperationException("Not implemented !");

	}

	@Override
	public Preferences parent() {
		throw new UnsupportedOperationException("Not implemented !");
	}

	@Override
	public void remove(String key) {
		throw new UnsupportedOperationException("Not implemented !");

	}

	@Override
	public void clear() throws BackingStoreException {
		throw new UnsupportedOperationException("Not implemented !");

	}

	@Override
	public void putLong(String key, long value) {
		throw new UnsupportedOperationException("Not implemented !");

	}

	@Override
	public long getLong(String key, long def) {
		throw new UnsupportedOperationException("Not implemented !");
	}

	@Override
	public void putBoolean(String key, boolean value) {
		throw new UnsupportedOperationException("Not implemented !");
	}

	@Override
	public boolean getBoolean(String key, boolean def) {
		throw new UnsupportedOperationException("Not implemented !");
	}

	@Override
	public void putFloat(String key, float value) {
		throw new UnsupportedOperationException("Not implemented !");
	}

	@Override
	public float getFloat(String key, float def) {
		throw new UnsupportedOperationException("Not implemented !");
	}

	@Override
	public void putDouble(String key, double value) {
		throw new UnsupportedOperationException("Not implemented !");
	}

	@Override
	public double getDouble(String key, double def) {
		throw new UnsupportedOperationException("Not implemented !");
	}

	@Override
	public void putByteArray(String key, byte[] value) {
		throw new UnsupportedOperationException("Not implemented !");
	}

	@Override
	public byte[] getByteArray(String key, byte[] def) {
		throw new UnsupportedOperationException("Not implemented !");
	}

	@Override
	public String[] keys() throws BackingStoreException {
		throw new UnsupportedOperationException("Not implemented !");
	}

	@Override
	public boolean nodeExists(String pathName) throws BackingStoreException {
		throw new UnsupportedOperationException("Not implemented !");
	}

	@Override
	public void removeNode() throws BackingStoreException {
		throw new UnsupportedOperationException("Not implemented !");
	}

	@Override
	public String name() {
		throw new UnsupportedOperationException("Not implemented !");
	}

	@Override
	public String absolutePath() {
		throw new UnsupportedOperationException("Not implemented !");
	}

	@Override
	public void flush() throws BackingStoreException {
		throw new UnsupportedOperationException("Not implemented !");
	}

	@Override
	public void sync() throws BackingStoreException {
		throw new UnsupportedOperationException("Not implemented !");
	}

}
```


----------



## SlaterB (20. Apr 2011)

inwiefern geht es denn nicht?
wie stellst du etwas fest, welche Beispiele verwendest du mit welchen Ergebnissen?
wo wird node() je aufgerufen?

wenn ich selbstständig wieder in den alten Thread schaue und dort in den JUnit-Test, 
dann testet der auch Parent-Beziehung die du überhaupt noch nicht implementiert hast 
(und ich garantiert nicht machen werden )


----------



## tanzverfuehrung (20. Apr 2011)

SlaterB hat gesagt.:


> inwiefern geht es denn nicht?
> wie stellst du etwas fest, welche Beispiele verwendest du mit welchen Ergebnissen?
> wo wird node() je aufgerufen?
> 
> ...



ok also DANKE!ich könnte dich grad abknutschen!
habe es soweit hinbekommen!
habe jetzt erst das mit parent gecheckt!!
(hätte ich das früher gecheckt, hätte ich das eventuell auch irgendwie mal ehr hin bekommen)

DANKE

habe jetzt paar junit test ohne parent abfrage gemacht und nun geht es auch
alle grün!
außer die mit parent abfrage!

aber das muss ich ja nur noch tun unD DANN habe ich es endlich!
:lol:


----------



## SlaterB (20. Apr 2011)

gut dass du diesen Test ohne parent nicht verrätst (Code postest), so können wir alle noch schön lange rätseln


----------



## tanzverfuehrung (20. Apr 2011)

SlaterB hat gesagt.:


> gut dass du diesen Test ohne parent nicht verrätst (Code postest), so können wir alle noch schön lange rätseln



ja ok tut mir leid!habe es hin bekommen
siehe mein letzten beitrag


so und hier habt ihr trozdem zwei junittest


```
@Test
	public void testAbsolutePath() throws Exception {
		Preferences b = simple.node("/a/b");
		
		assertThat(b.name(),is ("b"));
	}
	@Test
	public void testRelativePfad() throws Exception {
		 Preferences b = simple.node("a/b");
		 
		 assertThat(b.name(),is("b"));
	}
```

und in meiner klasse Preferences hat noch die methode name() gefehlt!


```
@Override
	public String name() {
		return name;
	}
```


jetzt halt nur noch die methode parent bearbeiten und dann alles supi


----------



## tanzverfuehrung (20. Apr 2011)

SlaterB hat gesagt.:


> wenn ich selbstständig wieder in den alten Thread schaue und dort in den JUnit-Test,
> dann testet der auch Parent-Beziehung die du überhaupt noch nicht implementiert hast
> (und ich garantiert nicht machen werden )




also das du es nicht für mich machst,ist klar...
aber kannst du mir nen gedanken anstoß geben?!


also das ist die methode in der api!

```
public abstract Preferences parent()
```
_Liefert den Eltern-Knoten zurück, oder null falls es sich bei diesem Knoten um einen Wurzel-Knoten handelt._

und wenn ich der Methode was übergebe,dann kommt nen fehler.und ich muss das
@Override
weg machen?!

darf ich...oder muss ich sie über schreiben?!???:L


und wieso kann ich die MEthode nicht einfach benutzen wie sie beschrieben ist?!
das hat was mit der implementierung zutun odeR?

```
public class SimplePreferences implements Preferences
```


----------



## SlaterB (20. Apr 2011)

> und wenn ich der Methode was übergebe
falsch

> und wieso kann ich die MEthode nicht einfach benutzen wie sie beschrieben ist?!
was spricht dagegen?

> gedanken anstoß geben?!
beim Anlegen des Objektes im Konstruktor den Parent übergeben, vorher z.B. in der Map suchen


----------



## tanzverfuehrung (20. Apr 2011)

SlaterB hat gesagt.:


> > und wenn ich der Methode was übergebe
> falsch



also das geht überhaupt nicht ???
und den zurückgabetyp darf ich auch nicht ändern,oder?



SlaterB hat gesagt.:


> >> und wieso kann ich die MEthode nicht einfach benutzen wie sie beschrieben ist?!
> was spricht dagegen?


???:Lnaja dann müsste ich sie doch nicht mehr implementieren, oder?
dann würden doch die junit.tests nicht fehlschlagen!

ODER bin grad richtig doof?!


und danke für den gedanken anstoß!


----------



## SlaterB (20. Apr 2011)

das Interface gibt die Signatur der Methode vor, Parameter kann man nicht ändern, den Rückgabetyp nur minimal, hier uninteressant,
die Methode wird von außen genau so verwendet wie sie ist,
du musst sie in deiner Klasse implementieren, so dass sie was sinnvolles zurückgibt, 
nicht mehr und nicht weniger ist deine Aufgabe,
natürlich impliziert das auch andere Änderungen wie der Vorschlag zum Konstruktor


----------



## tanzverfuehrung (21. Apr 2011)

SlaterB hat gesagt.:


> das Interface gibt die Signatur der Methode vor, Parameter kann man nicht ändern, den Rückgabetyp nur minimal, hier uninteressant,
> die Methode wird von außen genau so verwendet wie sie ist,
> du musst sie in deiner Klasse implementieren, so dass sie was sinnvolles zurückgibt,
> nicht mehr und nicht weniger ist deine Aufgabe,
> natürlich impliziert das auch andere Änderungen wie der Vorschlag zum Konstruktor





ich muss dich noch mal bitten meine klasse anzugucken,weil die parent() methode geht immer noch nicht einwandfrei!
ich habe es im konstruktor eingebunden
und da wo ich nen neues object von der klasse erzeuge, habe ich es auch angepasst.!
methode gibt auch das richtige zurück!
wo muss ich jetzt noch was ändern.in der node() methode odeR?


```
public class SimplePreferences implements Preferences {
	/**
	 * map wird mit String & Int Werten & mit dem dazugehörigen passendem
	 * Schlüssel gefüllt
	 */
	Map<String, Object> hashMap = new HashMap<String, Object>();
	/**
	 * nodeMap wird mit den PfadNAmen & mit dem dazugehörigen passendem
	 * Schlüssel gefüllt
	 */
	Map<String, SimplePreferences> nodeMap = new HashMap<String, SimplePreferences>();

	private String name;

	private Preferences parent;

	/**
	 * Erzeugt Knoten mit entsprechendem Namen
	 * 
	 * @param name
	 */
	public SimplePreferences(String name,Preferences parent) {
		super();
		this.name = name;
		this.parent = parent;
	}

	/**
	 * Methode packt den String Schlüssel & die String Wert in die Pereference
	 * und in die {@link SimplePreferences#hashMap}
	 * 
	 * @param key
	 *            Schlüssel
	 * @param value
	 *            Wert
	 */
	@Override
	public void put(String key, String value) {
		hashMap.put(key, value);
	}

	/**
	 * Methode überprüft ob in der {@link SimplePreferences#hashMap} zu dem
	 * String Schlüssel ein passender String Wert existiert
	 * 
	 * @param key
	 *            Schlüssel in der Preference
	 * @param defaultValue
	 *            Standertwert zu dem zugehörigen Schlüssel
	 * @return <li>defaultValue ,wenn die {@link SimplePreferences#hashMap} kein
	 *         Wert enthält. <li>value.toString ,der enthaltene Wert in der
	 *         {@link SimplePreferences#hashMap}
	 */
	@Override
	public String get(String key, String defaultValue) {
		Object value = hashMap.get(key);
		if (value == null)
			return defaultValue;
		return value.toString();
	}

	/**
	 * Methode packt den String Schlüssel & den Int Wert in die Pereference und
	 * in die {@link SimplePreferences#hashMap}
	 * 
	 * @param key
	 *            Schlüssel
	 * @param value
	 *            Wert
	 */
	@Override
	public void putInt(String key, int value) {
		hashMap.put(key, value);
	}

	/**
	 * Methode überprüft ob in der {@link SimplePreferences#hashMap} zu dem
	 * String Schlüssel ein passender Int Wert existiert
	 * 
	 * @param key
	 *            Schlüssel in der Preference
	 * @param defaultValue
	 *            Standertwert zu dem zugehörigen Schlüssel
	 * @return<li>value ,der enthaltene Wert in der
	 *                  {@link SimplePreferences#hashMap} <li>defaultValue ,wenn
	 *                  ein {@link NumberFormatException} ausgelöst wird
	 */
	@Override
	public int getInt(String key, int defaultValue) {
		String value = get(key, "" + defaultValue);
		try {
			return Integer.parseInt(value);
		} catch (NumberFormatException e) {
			return defaultValue;
		}
	}

	@Override
	public Preferences node(String pathName) {

		int index = pathName.indexOf("/");

		if (pathName == "")
			return this;

		if (index < 0) { // Wenn der index < 0 ist wurde kein Slash mehr
							// gefunden
			Preferences p = getNode(pathName);
			// und im pathName steht das letzte Element
			return p;
		}

		// Wenn der Index >=0 wurde ein Slash gefunden
		pathName = pathName.substring(++index); // Der Anfang des Strings bis
												// zum gefundenen Slash wird
												// abgeschnitten
		return node(pathName); // die Methode ruft sich selbst mit dem gekürzten
								// pathName auf
	}

	/**
	 * Prüft ob ein Pfad vorhanden ist, wenn kein pfad vorhanden ist, erzeuge
	 * ihn und gebe ihn zurück!
	 * 
	 * @param
	 * @return value, der gegebene oder erzeugte Pfad
	 */
	private Preferences getNode(String node) {

		SimplePreferences value = nodeMap.get(node); // prüfen ob knoten
														// vorhanden ist

		if (value == null) { // knoten nicht vorhanden
			value = new SimplePreferences(node,this); // knoten erzeugen
			nodeMap.put(node, value);
		}
		return value;
	}
	@Override
	public String name() {
		return name;
	}
//	/**
//	 * Liefert den Eltern-Knoten zurück, oder null falls es sich bei diesem
//	 * Knoten um einen Wurzel-Knoten handelt.
//	 */
	@Override
	public Preferences parent() {

		return parent;
	}

	@Override
	public String[] childrenNames() {
		throw new UnsupportedOperationException("Not implemented !");
	}

	@Override
	public void remove(String key) {
		throw new UnsupportedOperationException("Not implemented !");
	}

	@Override
	public void clear() throws BackingStoreException {
		throw new UnsupportedOperationException("Not implemented !");
	}

	@Override
	public void putLong(String key, long value) {
		throw new UnsupportedOperationException("Not implemented !");
	}

	@Override
	public long getLong(String key, long def) {
		throw new UnsupportedOperationException("Not implemented !");
	}

	@Override
	public void putBoolean(String key, boolean value) {
		throw new UnsupportedOperationException("Not implemented !");
	}

	@Override
	public boolean getBoolean(String key, boolean def) {
		throw new UnsupportedOperationException("Not implemented !");
	}

	@Override
	public void putFloat(String key, float value) {
		throw new UnsupportedOperationException("Not implemented !");
	}

	@Override
	public float getFloat(String key, float def) {
		throw new UnsupportedOperationException("Not implemented !");
	}

	@Override
	public void putDouble(String key, double value) {
		throw new UnsupportedOperationException("Not implemented !");
	}

	@Override
	public double getDouble(String key, double def) {
		throw new UnsupportedOperationException("Not implemented !");
	}

	@Override
	public void putByteArray(String key, byte[] value) {
		throw new UnsupportedOperationException("Not implemented !");
	}

	@Override
	public byte[] getByteArray(String key, byte[] def) {
		throw new UnsupportedOperationException("Not implemented !");
	}

	@Override
	public String[] keys() throws BackingStoreException {
		throw new UnsupportedOperationException("Not implemented !");
	}

	@Override
	public boolean nodeExists(String pathName) throws BackingStoreException {
		throw new UnsupportedOperationException("Not implemented !");
	}

	@Override
	public void removeNode() throws BackingStoreException {
		throw new UnsupportedOperationException("Not implemented !");
	}

	@Override
	public String absolutePath() {
		throw new UnsupportedOperationException("Not implemented !");
	}

	@Override
	public void flush() throws BackingStoreException {
		throw new UnsupportedOperationException("Not implemented !");
	}

	@Override
	public void sync() throws BackingStoreException {
		throw new UnsupportedOperationException("Not implemented !");
	}

}
```


----------



## tanzverfuehrung (21. Apr 2011)

und meine junit tests die  noch nicht gehen sind



```
@Test
	public void testParentAbsolutePath() throws Exception {
		Preferences b = simple.node("/a/b");
		assertThat(b.parent().name(), is("a"));
	}

	@Test
	public void testParentRelativePath() throws Exception {
		Preferences b = simple.node("a/b");
		assertThat(b.parent().name(), is("a"));
	}
```

also irgendwie  muss ich dann auch noch zwischen absoluten und relativen pfad unterscheiden!
ich würde sagen warscheinlich mit der methode

```
public boolean isAbsolue()
```
oder?

aber eigentlich müsste ja ein test wenigstens grün sein:bahnhof:


----------



## Crian (21. Apr 2011)

Und wie sieht deine

```
public Preferences parent() {
    // dein code
}
```
aus?

Ob der Pfad absolut ist oder nicht musst du anfangs beim Parsen des selben festhalten. Sonst kannst du das hinterher nicht mehr an der verketteten Liste erkennen.


----------



## SlaterB (21. Apr 2011)

ich habe gerade viel eingetippt, hauptsächlich Gemecker, aber ging verloren,
Kurzversion
[c] value = new SimplePreferences(node,this);[/c]
this ist und bleibt und wird vielleicht immer bleiben: Müll,

du musst den richtigen Parent übergeben, wie das geht ist gewiss nicht leicht, obwohl bestenfalls nur wenige Befehle (Stichwort: parent-pfad bestimmen, in der Map nachschauen)
ich möchte da aber nicht weiter für dich programmieren, das ganze Programm ist anscheinend fern deiner Vorstellungskraft

das war jetzt garantiert mein letztes Posting hier


----------



## tanzverfuehrung (21. Apr 2011)

Crian hat gesagt.:


> Und wie sieht deine
> 
> ```
> public Preferences parent() {
> ...




```
/**
   * Liefert den Eltern-Knoten zurück, oder null falls es sich bei diesem
   * Knoten um einen Wurzel-Knoten handelt.
   */
    @Override
    public Preferences parent() {
 
        return parent;
    }
```


----------



## Crian (21. Apr 2011)

Und warum geht es dann nicht? Vielleicht muss man doch mal einen Blick auf das Ganze werfen.


Was vermutlich hilfreich wäre: Stell dein Projekt doch mal strukturiert vor.
Was soll es leisten.
Was sind die Vorgaben.
Was hast du bisher erreicht.

Ich hab irgendwie das Gefühl, dass da zu viel durcheinander geht. Aber ich kann da natürlich auch falsch liegen.


----------



## tanzverfuehrung (21. Apr 2011)

also ich ahbe soweit eigentlich jetzt Alles hin bekommen nur der absolute pfad geht leider nicht nciht
sonst geht alles!
also parent methode geht!
habe ich alles mit juintTEst getestet!
das ist z.b. einer der juint test

```
@Test
	public void testParentAbsolutePath() throws Exception {
		Preferences b = simple.node("/a/b");
		assertThat(b.parent().name(), is("a"));
	}
```

meine code dazu

```
@Override
	public Preferences node(String pathName) {
		

		if (pathName.isEmpty())
			return this;
		int index = pathName.indexOf("/");
		
		
if(index == 0){			//absoluter Pfad
	while (parent.equals(null)) {
	parent();	
	}
	int parentIndex = (parent).toString().indexOf("/");
	
	pathName = parent.toString().substring(parentIndex+1);
}


		if (index < 0) { // Wenn der index < 0 ist wurde kein Slash mehr
							// gefunden
			Preferences p = getOrCreateNode(pathName);
			// und im pathName steht das letzte Element
			return p;
		}
		String[] split = pathName.split("/", 2);	
		
		Preferences node1 = node(split[0]);
		Preferences node2 = node1.node(split[1]);
		return node2;
		
		
	}

	/**
	 * Prüft ob ein Pfad vorhanden ist, wenn kein pfad vorhanden ist, erzeuge
	 * ihn und gebe ihn zurück!
	 * 
	 * @param
	 * @return value, der gegebene oder erzeugte Pfad
	 */
	private Preferences getOrCreateNode(String nodeName) {

		SimplePreferences value = nodeMap.get(nodeName); // prüfen ob knoten
														// vorhanden ist
		
		if (value == null) { // knoten nicht vorhanden
			value = new SimplePreferences(nodeName,this); // knoten erzeugen
			nodeMap.put(nodeName, value);
		}
		return value;
	}

	@Override
	public String name() {
		return name;
	}
	
	/**
	 * Liefert den Eltern-Knoten zurück, oder null falls es sich bei diesem
	 * Knoten um einen Wurzel-Knoten handelt.
	 */
	@Override
	public Preferences parent() {
		return parent;
	}
```


und mit dieses abfrage wolle ich den absoluten pfad behandeln!


```
if(index == 0){			//absoluter Pfad
	while (parent.equals(null)) {
	parent();	
	}
	int parentIndex = (parent).toString().indexOf("/");
	
	pathName = parent.toString().substring(parentIndex+1);
}
```


----------



## tanzverfuehrung (21. Apr 2011)

oder ist mein Junit test falsch!?!?!?!??!?!
???:L


----------



## luatigernam (22. Apr 2011)

Worum gehts hier?


----------

