001: package webman.stager;
002:
003: import java.io.*;
004: import java.net.*;
005: import java.util.*;
006: import org.apache.log4j.*;
007:
008: /**
009: * Diese Klasse stellt gemeinsame Funkionalität für SiteTransmitter und SiteReceiver bereit
010: * @author $author$
011: * @version $revision$
012: */
013: public abstract class Stager {
014: /**Das Logfile*/
015: protected FileWriter logfile = null;
016:
017: /**Zeilenumbruchszeichen*/
018: protected static final String NEWLINE = System
019: .getProperty("line.separator");
020: /**Log4J-Categor<*/
021: protected static Category CAT = Category.getInstance(Stager.class); //wird in den Subklassen geeignet überschrieben
022: /**Ausgabestrom*/
023: protected PrintStream outStream = null;
024:
025: /**initialisiert die Log4J-Umgebung*/
026: static {
027: //DOMConfigurator.configure(Stager.class.getResource("stager_log4j.xml"));
028: URL url = Stager.class.getResource("Stager_log4j.properties");
029: //Dieser Umweg ist scheinbar erforderlich,um einen merkwürdigen Bug auf Jaheira zu umgehen:
030: //Exception in thread "main" java.lang.ExceptionInInitializerError: java.lang.NullPointerException
031: //at org.apache.log4j.PropertyConfigurator.doConfigure(PropertyConfigurator.java:428)
032: //at org.apache.log4j.PropertyConfigurator.configure(PropertyConfigurator.java:329)
033: //at webman.stager.Stager.(Stager.java:20)
034: PropertyConfigurator.configure(url);
035: }
036:
037: /**
038: * markiert einen String in HTML als Datei (durch Kursivschrift)
039: * @param str der zu markierende String
040: * @return der markierte String
041: */
042: protected String markAsFile(String str) {
043: return "\"<i>" + str + "</i>\"";
044: }
045:
046: // ============== socket operations ==================
047:
048: /**
049: * schreibt einen String in ein Socket
050: * @param s das Socket
051: * @param message der String
052: * @throws Exception wenn was beim Schreiben schief geht
053: */
054: protected void printToSocket(Socket s, String message)
055: throws Exception {
056: PrintWriter out = null;
057: try {
058: out = new PrintWriter(s.getOutputStream());
059: out.println(message);
060: out.flush();
061: } catch (Exception e) {
062: throw new Exception("Unable to write to socket: " + e);
063: }
064: }
065:
066: /**
067: * liest einen String vom Socket
068: * @param s das Socket
069: * @return der gelesene String
070: * @throws Exception wenn was beim Lesen schief geht
071: */
072: protected String readFromSocket(Socket s) throws Exception {
073: BufferedReader in = null;
074: String line = null;
075: in = new BufferedReader(new InputStreamReader(s
076: .getInputStream()));
077: line = in.readLine();
078: return line;
079: }
080:
081: // ------------- logging --------------------
082:
083: /**
084: * öffnet eine Datei als Logfile
085: * @param filename der Dateiname
086: * @param append wenn true, dann wird eine bestehende Datei nicht überschrieben, sondern daran angeknüpft
087: * @return einen FileWriter auf das geöffnete Logfile (null, wenn kein Logfile geöffnet wurde)
088: */
089: protected FileWriter openLog(String filename, boolean append) {
090: try {
091: return new FileWriter(filename, append);
092: } catch (Exception e) {
093: CAT.error("Unable to open logfile: ", e);
094: }
095: return null;
096: }
097:
098: /**
099: * schreibt einen String in das Logfile
100: * @param str der auszugebene String
101: */
102: protected void log(String str) {
103: CAT.info("log(): " + str);
104: if (logfile != null) {
105: if (!str.endsWith(NEWLINE)) {
106: str += NEWLINE;
107: }
108: try {
109: logfile.write(str);
110: logfile.flush();
111: } catch (Exception e) {
112: CAT.error("Could not write to logfile: ", e);
113: }
114: }
115: }
116:
117: /**
118: * schließt das logfile
119: */
120: protected void closeLog() {
121: if (logfile != null) {
122: try {
123: logfile.flush();
124: logfile.close();
125: logfile = null; //als Kennzeichen, dass man nicht mehr reinschreiben kann
126: } catch (Exception e) {
127: CAT.warn("Unable to close logfile", e);
128: }
129: }
130: }
131:
132: /**
133: * registriert einen SSL-Provider (Standard: SUN)
134: * @return einen String mit einer evenutellen Fehlermeldung, ansonsten null
135: */
136: protected String initSSL() {
137: try {
138: // Dynamic registration of JSSE provider
139: java.security.Security
140: .addProvider(new com.sun.net.ssl.internal.ssl.Provider());
141: } catch (Exception e) {
142: return "unable to init ssl: " + e;
143: }
144: return null;
145: }
146:
147: /**
148: * berechnet aus 2 Pfaden einen absoluten Pfad
149: * @param docroot der Ausgangspfad; relativ zu diesem wird filename ausgewertet
150: * @param filename der Pfad relativ zur docroot
151: * @return der zusammengefasste Pfad von docroot und filename, es sei denn, filename ist schon absolut; dann wird filename zurückgegeben
152: * @throws IllegalArgumentException wenn filename relativ ist aber docroot nicht angegeben wurde
153: * @throws IOException wenn beim Filehandling irgendwas schief geht
154: */
155: protected String getAbsoluteName(String docroot, String filename)
156: throws IllegalArgumentException, IOException {
157: if (new File(filename).isAbsolute()) {
158: return new File(filename).getCanonicalPath();
159: }
160: if (docroot == null) {
161: throw new IllegalArgumentException(
162: "docroot must be provided if filename is relative");
163: }
164: return new File(docroot, filename).getCanonicalPath();
165: }
166:
167: /**
168: * schreibt einen String in den Ausgabestrom sowie in das Logfile
169: * @param str der auszugebene String
170: */
171: protected abstract void logAndPrint(String str);
172:
173: /**
174: * markiert einen String (in HTML) als Fehler (durch rote Schriftfarbe) und gibt ihn im Logfile und in Log4J aus
175: * @param str der auszugebene Fehlerstring
176: */
177: protected void error(String str) {
178: logAndPrint("<FONT color=#ff5555>" + str + "</FONT>");
179: CAT.error(str);
180: }
181:
182: /**
183: * markiert einen String (in HTML) als Fehler (durch rote Schriftfarbe) und gibt ihn im Logfile und in Log4J aus
184: * @param str der auszugebene Fehlerstring
185: * @param t verursachende Exception
186: */
187: protected void error(String str, Throwable t) {
188: logAndPrint("<FONT color=#ff5555>" + str + " [" + t.toString()
189: + "]</FONT>");
190: CAT.error(str, t);
191: }
192:
193: /**
194: * wertet den Rückgabewert einer Methode aus; schreibt dabei eine Fehlermeldung mit error() und eine Erfolgsmeldung mit logAndPrint()
195: * @param result der Rückgabestring einer Methode (null oder Fehlermeldung)
196: * @param msg die mit der Auswertung auszugebene Message
197: * @return true wenn die Methode fehlerlos war (also result == null)
198: */
199: boolean methodSucceed(String result, String msg) {
200: if (result != null) {
201: error("<B>" + msg + " ... failed: " + result
202: + "</B><BR><BR>");
203: CAT.error(msg + " failed: " + result);
204: return false;
205: }
206: logAndPrint("<B>" + msg + " ... done" + "</B><BR><BR>");
207: return true;
208: }
209:
210: /**
211: * wertet den Rückgabewert einer Methode aus; schreibt dabei eine Fehlermeldung mit error() und eine Erfolgsmeldung mit logAndPrint()
212: * @param result der Rückgabestring einer Methode (null oder Fehlermeldung)
213: * @return true wenn die Methode fehlerlos war (also result == null)
214: */
215: boolean methodSucceed(String result) {
216: return methodSucceed(result, "");
217: }
218:
219: /**
220: * liefert InputStream auf eine Resource, deren Pfad relativ zum Pfad einer Klasse angegeben wird
221: * @param baseClass die Klasse, deren Pfad als Basis für die Pfadberechnung dient
222: * @param path der relative oder absolute (der wird dann so belassen) Dateipfad
223: * @return ein InputStream zu dieser Resource
224: * @throws IOException wenn die Resource nicht vorhanden ist oder sonstige Fehler auftreten
225: */
226: public static InputStream getResourceInputStream(Class baseClass,
227: String path) throws IOException {
228: if (!(new File(path).isAbsolute())) {
229: //Klassennamen bestimmen (getName() liefert noch Klassenpfad (Packagestruktur) mit)
230: String base = baseClass.getName().substring(
231: baseClass.getName().lastIndexOf(".") + 1);
232: //aus dem eigentlichen Klassennamen ne URL für den (Klassen)-Pfad basteln
233: base = new File(baseClass.getResource(base + ".class")
234: .getFile()).getParent();
235: path = new File(base, path).getCanonicalPath();
236: }
237: try {
238: return (new URL("file:" + path)).openStream();
239: } catch (Exception e) {
240: throw new IOException(e.toString());
241: }
242: }
243: }
|