# Decorator Pattern: Input mit Caesar, Output mit Großbuchstaben



## devo22 (12. Dez 2011)

Hi! Ich soll zwei Decorator-Klassen für java.io schreiben:

1) einen Reading-Decorator, der eine Eingabe mit der Caesar-Verschlüsselung verschlüsselt, und
2) einen Writing-Decorator, der einen Text in Großbuchstaben umwandelt.

Hab mich zuerst mal an das Reading gemacht und versucht, die read-Methoden aus der FilterInputStream-Klasse zu überschreiben. Leider funktioniert das noch nicht, der Stream wird unverändert ausgegeben.

Und was das Writing angeht, scheitere ich am Überschreiben der write-Methoden aus OutputStream 

Kann mir jemand helfen? Vielen Dank schon mal!



```
import java.io.*;

public class CryptInputStream extends FilterInputStream {

public CryptInputStream(InputStream in) {
super(in);
}
public String read(String input) throws IOException {
int c = super.read();

char s; int i;
String output = new String();
int len = input.length();

for (i = 0; i < len; i++) {
	s = input.charAt(i);
	if (s == ' ');
	else {
	output = output + (char)((s - 65 + c)%26+65);
	}
}
return output;
} }
```


```
import java.io.*;

public class UpperCaseOutputStream extends OutputStream {

public UpperCaseOutputStream(OutputStream out) {
super(out);
}

public void write(byte b[], int off, int len) throws IOException {

for (int i = 0 ; i < len ; i++) {
			b[i] = (byte)Character.toUpperCase((char)b[i]);
         write(b[off + i]);
     }  }
}
```


----------



## devo22 (12. Dez 2011)

so, ich hab weitergearbeitet. Nur leider funktioniert da gar nix 

*READING DECORATOR:*


```
import java.io.*;

public class CryptInputStream extends FilterInputStream {

public CryptInputStream(InputStream in) {
super(in);
}
public String read(String input) throws IOException {
int c = super.read();

char s; int i;
String output = new String();
int len = input.length();

for (i = 0; i < len; i++) {
	s = input.charAt(i);
	if (s == ' ');
	else {
	output = output + (char)((s - 65 + c)%26+65);
	}
}
return output;
} }
```

*WRITING DECORATOR:*


```
import java.io.*;

public class UpperCaseOutputStream extends OutputStream {

protected OutputStream out;

public UpperCaseOutputStream(OutputStream out) {
    this.out = out;
    }

   public void write(int b) throws IOException {
		char c = (char) b;
		if (Character.isLowerCase(c)) {
			c = Character.toUpperCase(c);
			}
		out.write((int) c);
	}

    public void write(byte b[]) throws IOException {
		write(b, 0, b.length);
    }

    public void write(byte b[], int off, int len) throws IOException {
    
		for (int i = off; i < (off + len); i++) {
			char c = (char) b[i];
			if (Character.isLowerCase(c)) {
				c = Character.toUpperCase(c);
				}
			out.write((int) c);
			}
		}	
	}
```

*DEMO:*


```
import java.io.*;

public class DecoratorDemo {

public static void main(String[] args) {
		int c;
		CryptInputStream input = null;
		UpperCaseOutputStream output = null;
		
		try {
				
		input = new CryptInputStream(new FileInputStream("test.txt"));
		
		while((c = input.read()) >= 0) {
		System.out.print((char)c);
		}
		
		output = new UpperCaseOutputStream(input);
		}
				
		catch (IOException e) { e.printStackTrace(); }
   }
}
```


----------



## Final_Striker (12. Dez 2011)

> Hab mich zuerst mal an das Reading gemacht und versucht, die read-Methoden aus der FilterInputStream-Klasse zu überschreiben. Leider funktioniert das noch nicht, der Stream wird unverändert ausgegeben.



Der FilterInputStream hat keine Methode mit dieser Signatur

```
public String read(String input) throws IOException
```

Bist du sicher, dass du die Methoden überschreiben sollst?


----------



## devo22 (12. Dez 2011)

stimmt, danke. Ich ändere die reading-Klasse jetzt so, dass sie einfach die InputStream extended.

Was das Überschreiben angeht - ja, bin mir schon ziemlich sicher, dass ich sie überschreiben soll. Zumindest in allem, was ich zum Decorator und den bestehenden I/O-Klassen gelesen habe, steht, dass das so geht.


----------



## devo22 (12. Dez 2011)

Also den Output mit UpperCase habe ich jetzt hinbekommen. Ich hänge aber beim Caesar-Verschlüsseln im Input ... hab keine Ahnung, wie ich die Verschlüsselung im Input-Decorator einbinden soll  hat da jemand eine Idee für mich?


----------



## devo22 (12. Dez 2011)

ich bin hier kurz vorm Verzweifeln  habs auf eigene Faust versucht, aber die Caesar-Verschlüsselung funktioniert noch immer nicht. Wär echt super, wenn mir jemand einen Tipp geben könnte - danke schon mal!

*INPUT-DECORATOR:*


```
import java.io.*;
import java.util.Scanner;

public class CryptInputStream extends InputStream {

protected InputStream in;
private static final String abc = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

public CryptInputStream(InputStream in) {
this.in = in;
}

public int read() throws IOException {
return in.read();
}

public int read(byte b[], int off, int len) throws IOException {
	int result = super.read(b, off, len);
	for (int i = off; i < off+result; i++) {
	}
	return result;
	}

public String crypt(InputStream in) {
	int key = 1;
	String s = convert(in);
    StringBuilder sb = new StringBuilder(s.length());
    for (int i = 0; i < s.length(); i++) {
            int pos = abc.indexOf(s.charAt(i));
            if (pos == -1) 
                sb.append(" ");
            else
                sb.append(abc.charAt((pos+key)%26));
        }
        return sb.toString();
    }
	
public String convert(InputStream in) { 
    return new Scanner(in).useDelimiter("\\A").next();
	}
   }
```

*DEMO:*


```
import java.io.*;

public class DecoratorDemo {

public static void main(String[] args) {
		int c;
		CryptInputStream input = null;
		CryptInputStream input2 = null;
		UpperCaseOutputStream output = null;
		
		try {
				
		input = new CryptInputStream(new FileInputStream("test.txt"));
		input2 = input;
		output = new UpperCaseOutputStream(new FileOutputStream("test2.txt"));
		
		input2.crypt(input);
		
		while((c = input.read()) >= 0) {
        output.write(c);
        }

		input.close();
		output.close();
		}
				
		catch (IOException e) { e.printStackTrace(); }
   }
}
```


----------



## Beni (13. Dez 2011)

Ein InputStream hat genau eine abstrakte Methode "int read()", genau diese eine Methode musst du überschreiben und dort den Cäsar Code anwenden.

"read(byte[],int,int)" ist bereits implementiert und benutzt "read()", es gibt für dich also keinen Grund diese Methode nochmal zu implementieren.


----------



## devo22 (13. Dez 2011)

Danke, habs hinbekomnen!


----------

