package AstroOL; import java.util.*; import java.applet.*; import java.lang.reflect.*; /** Wrapperklasse, um in HTML-Seiten auf die Funktionen der Klassen {@link Calculator}, {@link Mundan} und {@link LowPrecCalculator} zugreifen zu können. Instanzen des CalculatorApplets sind per Komposition mit Instanzen von <code>Calculator</code>, <code>ICalculator</code> und <code>Mundan</code> verknüpft. <p> Um von HTML-Seiten aus auf Attribute und Methoden eines Java-Objekts zuzugreifen, braucht man nur die betreffende Klasse von <code>java.applet.Applet</code> erben zu lassen. In Fällen, wo dies nicht möglich ist, da die Klasse bereits von einer anderen Klasse erbt oder eine Vererbung von <code>java.applet.Applet</code> aus anderen Gründen nicht gewünscht wird, verwendet man eine zusätzliche Wrapperklasse. Die Wrapperklasse ist ein - meist nicht-visuelles - Applet, das in seinen globalen Attributen Referenzen auf verschiedene andere Objekte enthält. Methodenaufrufe werden von der Wrapperklasse an diese anderen Objekte delegiert. <p> Das <code>CalculatorApplet</code> ist eine solche Wrapperklasse. Es kann verschiedene astrologische Berechnungen übernehmen, die es an die gewählte <code>ICalculator</code>-Instanz, an den <code>Calculator</code> oder an die Klasse <code>Mundan</code> weiterreicht. */ public class CalculatorApplet extends Applet { /** Instanz des Rechners für astrologische Berechnungen allgemeiner Natur */ public Calculator calc; /** Instanz des Haus- und Ephemeriden-Rechners */ public ICalculator iCalc; /** Instanz des Rechners für Berechnungen auf der Himmelssphäre (rund um den Begriff der mundanen Position). */ public Mundan m; private Hashtable methods; /** Initialisierung: Instanziierung der verschiedenen astrologischen Rechner. */ public void init() { double xjd=0d; String s; int i; String sPhi, sSt, sEE; // Calculator-Instanz calc = new Calculator(); // Instanz des Rechners für Planeten- und Hausberechnungen s = getParameter("calculator"); if (s == null) // Calculator ist der Default iCalc = (ICalculator) calc; else if (s.equals("LowPrecCalculator") || s.equals("AstroOL.LowPrecCalculator")) // LowPrecCalculator für eine billige Ephemeride am Frontend iCalc = (ICalculator) new Calculator(); else // Generische Instanziierung eines anderen Calculators durch // Aufruf des Defaultkonstruktors try { iCalc = (ICalculator) Class.forName(s).newInstance(); } catch (Exception ex) { ex.printStackTrace(); iCalc = (ICalculator) new Calculator(); } // Falls vorhanden, dem Calculator die servletURL mitteilen if ((s = getParameter("servletURL")) != null) iCalc.setServletURL(s); // Mundanrechner initialisieren if ((sPhi = getParameter("phi"))==null) sPhi=d2s(Calculator.DEFAULT_LAT); if ((sSt = getParameter("st")) ==null) {xjd=Calculator.thisjd(); sSt = d2s(LowPrecCalculator.lst( LowPrecCalculator.gst0(xjd), (xjd-.5d-Math.floor(xjd-.5d))*24, Calculator.DEFAULT_LON)); } if ((sEE = getParameter("ee")) ==null) {if (xjd==0d) xjd=Calculator.thisjd(); sEE = d2s( LowPrecCalculator.tilt(xjd)); } setMundan(sSt,sPhi,sEE); // Alle Methodennamen in einer Hashtable merken Method[] marr = this.getClass().getMethods(); s = ""; methods = new Hashtable(); for (i = 0; i < marr.length; i++) methods.put(marr[i].getName(),s); } /** Doppeltgenaue Gleitkommazahl in einen String wandeln. Dabei wird als Dezimaltrenner ein Komma "," verwendet (der Punkt ist als Sexagesimal-Trennzeichen reserviert). */ public String d2s(double x) { String y = " "+Double.toString(x); int i = y.indexOf('.'); if (i >=0) return y.substring(1,i)+","+y.substring(i+1); else return y.substring(1); } private String dms(double x, long format) { String y = calc.dms(x,format); String z = ""; char s; for (int i=0; i<y.length();i++) { s = y.charAt(i); if ((s == ' ')||(s=='"')) continue; if (s == '°') z += '.'; else if (s== '\'') z += '.'; else z += Character.toLowerCase(s); } return z; } /** Dezimal- oder Sexagesimalzahl in ein <code>double</code>-Feld konvertieren. Als Dezimaltrennzeichen gilt das Komma ",". Zur Trennung der Stellen von Sexagesimalzahlen können Punkt ".", die Zeichen für Grad, Minuten und Sekunden (°'") sowie die Zeichen für Stunden, Zeitminuten und Zeitsekunden (hms) verwendet werden. Zeitangaben werden mit 15 multipliziert. Für den String "6h" wird also die Zahl 90 zurückgegeben. */ public double s2d(String x) { double y = 0; int i = x.indexOf(','),j; long l=0,mul=1; boolean hms = false; if (i >= 0) return Double.valueOf(x.substring(0,i)+"."+x.substring(i+1)).doubleValue(); else { y = Degree.getValue(x); if ((x.indexOf('h') >=0) || (x.indexOf('m') >=0)) hms = true; return (hms) ? y*15d : y; } } /** Einen String in eine lange Ganzzahl wandeln. Es wird die Klass <code>java.lang.Long</code> zum Parsen verwendet. */ public long toLong(String x) { return Long.valueOf(x).longValue(); } /** Einen String in eine gewöhnliche Ganzzahl wandeln. Es wird die Klass <code>java.lang.Integer</code> zum Parsen verwendet. */ public int toInt(String x) { return Integer.valueOf(x).intValue(); } /** Einen String in ein Boolesches Feld wandeln. Es wird die Klass <code>java.lang.Boolean</code> zum Parsen verwendet. */ public boolean toBoolean(String x) { return Boolean.valueOf(x).booleanValue(); } /** Feststellen, ob eine Methode des angegebenen Namens existiert. Es wird nur der Methodenname geprüft, nicht die Signatur. Sobald also auch nur eine Methode des angegebenen Namens existiert, gleich welcher Signatur, wird <code>true</code> zurückgegeben, sonst <code>false</code>. */ public boolean isMethod(String name) { return (methods.get(name)!=null); } /** Den Mundanrechner eichen. Hierzu werden Werte für die Sternzeit, die Ekliptikschiefe und die geographische Breite benötigt. Die Werte werden als String angegeben und werden zunächst mit der Methode {@link #s2d(String)} in eine Gleitkommazahl verwandelt. */ public void setMundan(String st, String lat, String ee) { if (m == null) m = new Mundan( s2d(st), s2d(lat), s2d(ee), Mundan.PLACIDUS ); else { m.setSiderealTime(s2d(st)); m.setEE(s2d(ee)); m.setLatitude(s2d(lat)); } } // Methoden der Calculator-Klasse /** Wrapper für {@link Calculator#acos(double) Arcuscosinus im Gradmass} */ public String acos(String x) { return dms(calc.acos(s2d(x)),calc.SEC); } /** Wrapper für {@link Calculator#arcdiff(double,double) reduzierte Winkeldifferenz} */ public String arcdiff(String x, String y) { return dms(calc.arcdiff(s2d(x),s2d(y)),calc.SEC); } /** Wrapper für {@link Calculator#arcdiffAbs(double,double) reduzierte absolute Winkeldifferenz} */ public String arcdiffAbs(String x, String y) { return dms(calc.arcdiffAbs(s2d(x),s2d(y)),calc.SEC); } /** Wrapper für {@link Calculator#asin(double) Arcussinus im Gradmass} */ public String asin(String x) { return dms(calc.asin(s2d(x)),calc.SEC); } /** Wrapper für {@link Calculator#atan(double) Arcustangens im Gradmass} */ public String atan(String x) { return dms(calc.atan(s2d(x)),calc.SEC); } /** Wrapper für {@link Calculator#atan2(double,double) phasengenauen Arcustangens im Gradmass} */ public String atan2(String x, String y) { return dms(calc.atan2(s2d(x),s2d(y)),calc.SEC); } /** Wrapper für {@link Calculator#date(double) Kalenderdatum aus Julianischem Datum } */ public String calendarDate(String jd) { return calc.date(s2d(jd)); } /** Wrapper für {@link Calculator#date(double) Kalenderdatum aus Julianischem Datum, Synonym für Funktion {@link #calendarDate(String) calendarDate()} } */ public String date(String jd){ return calc.date(s2d(jd)); } /** Wrapper für {@link Calculator#cos(double) Cosinus im Gradmass} */ public String cos(String x) { return d2s(calc.cos(s2d(x))); } /** Wrapper für {@link Calculator#dms(double,long) sekundengenaue Ausgabe einer Sexagesimalzahl} */ public String dms(String x){ return dms(s2d(x),calc.SEC); } /** Wrapper für {@link Calculator#dms(double,long) Formatierte Ausgabe einer Sexagesimalzahl} */ public String dms(String x, String format){ return dms(s2d(x),toLong(format)); } /** Wrapper für {@link Calculator#fabs(double) Absolutbetrag} */ public double fabs(String x){ return calc.fabs(s2d(x)); } /** Wrapper für {@link Calculator#fmod(double,double) Restbildung (modulo)} */ public String fmod(String x, String a){ return d2s(calc.fmod(s2d(x),s2d(a))); } /** Wrapper für {@link Calculator#fmod360(double) Restbildung auf 360} */ public String fmod360(String x){ return dms(calc.fmod360(s2d(x)),calc.SEC); } /** Wrapper für {@link Calculator#fract(double) Dezimalteil einer Zahl} */ public String fract(String x){ return d2s(calc.fract(s2d(x))); } // Methoden der ICalculator-Klasse /** Wrapper für {@link ICalculator#getPlanetsAndHouses(double,double,double,double[],double[]) Berechnung von Planeten und Häusern} */ public String getPlanetsAndHouses(String jd_ut, String lon, String lat){ double[] pl = new double[10], h = new double[13]; iCalc.getPlanetsAndHouses(s2d(jd_ut),s2d(lon),s2d(lat),pl,h); return "planets:"+calc.doubleList(pl)+"\nhouses:"+calc.doubleList(h); } /** Wrapper für {@link Calculator#getPlanetsAndHouses(String,double[],double[]) Berechnung von Planeten und Häusern mittels eines Servlets.} Der Parameter <code>urlstring</code> gibt die vollständige URL (inklusive Query-String) an. @return Die Rückgabe des Servlets als String in der Form <code>"planets:...\nhouses:..."</code>*/ public String getPlanetsAndHouses(String urlstring){ double[] pl = new double[10], h = new double[13]; calc.getPlanetsAndHouses(urlstring,pl,h); return "planets:"+calc.doubleList(pl)+"\nhouses:"+calc.doubleList(h); } /** Wrapper für {@link Calculator#julianDate(int,int,int,double) Julianisches Datum aus Kalenderdatum}. @param dmy String mit dem Kalenderdatum, z.B. 15.7.2004 @return Julianisches Datum */ public String jd(String dmy) { StringTokenizer st = new StringTokenizer(dmy, "."); String x[] = new String[3]; int i = 0; while (st.hasMoreTokens()) { x[i++] = st.nextToken(); } return julianDate(x[2],x[1],x[0], "0."); } /** Wrapper für {@link Calculator#julianDate(int,int,int,double) Julianisches Datum aus Kalenderdatum}. In dieser Form können Jahr, Monat, Tag und Ephemeridenzeit als einzelne Argumente übergeben. */ public String julianDate(String year, String month, String day, String et){ return d2s(calc.julianDate(toInt(year),toInt(month),toInt(day),s2d(et))); } /** Wrapper für {@link Calculator#parseTimePlace(String,double[]) Parsen eines Datum/Zeit-Strings}. Der aus drei Gleitkommazahlen bestehende Rückgabewert von <code>Calculator.parseTimePlace()</code> wird als String in einer komma-separierten Liste zurückgegeben. */ public String parseTimePlace(String in){ double[] x = new double[3]; calc.parseTimePlace(in,x); return calc.doubleList(x); } /** Wrapper für {@link Calculator#renderTimePlace(double,double,double) Aufbauen eines Datum/Zeit-Strings}. */ public String renderTimePlace(String jd, String lon, String lat){ return calc.renderTimePlace(s2d(jd),s2d(lon),s2d(lat)); } /** Wrapper für {@link Calculator#renderTimePlace(double,double,double,long) Formatiertes Aufbauen eines Datum/Zeit-Strings}. */ public String renderTimePlace(String jd, String lon, String lat, String format){ return calc.renderTimePlace(s2d(jd),s2d(lon),s2d(lat),toLong(format)); } /** Setzen der Servlet-URL für die ICalculator-Instanz */ public void setServletURL(String iServletURL){ iCalc.setServletURL(iServletURL); } /** Wrapper für {@link Calculator#sgn(double) Signumfunktion } */ public byte sgn(String x){ return calc.sgn(s2d(x)); } /** Wrapper für {@link Calculator#sin(double) Sinus im Gradmass } */ public String sin(String x){ return d2s(calc.sin(s2d(x))); } /** Wrapper für {@link Calculator#tan(double) Tangens im Gradmass } */ public String tan(String x){ return d2s(calc.tan(s2d(x))); } /** Wrapper für {@link Calculator#thisjd() Julianisches Datum zur aktuellen Zeit } */ public String thisjd() { return d2s(calc.thisjd()); } // Methoden der Mundanklasse /** Wrapper für {@link Mundan#aclaenge(double) Länge aus schräger Aufsteigung } */ public String aclaenge(String oa) { return dms(m.aclaenge(s2d(oa)),calc.ECL+calc.SEC); } /** Wrapper für {@link Mundan#aclaenge(double,double) Länge aus schräger Aufsteigung und Polhöhe } */ public String aclaenge(String oa, String phi) { return dms(m.aclaenge(s2d(oa),s2d(phi)),calc.ECL+calc.SEC); } /** Wrapper für {@link Mundan#ad(double) Aszensionsdifferenz aus Deklination } */ public String ad(String d) { return dms(m.ad(s2d(d)),calc.SEC); } /** Wrapper für {@link Mundan#ad(double,double) Aszensionsdifferenz aus Deklination und Polhöhe } */ public String ad(String d, String ph) { return dms(m.ad(s2d(d),s2d(ph)),calc.SEC); } /** Wrapper für {@link Mundan#decl(double) Deklination aus ekliptikaler Länge } */ public String decl(String l) { return dms(m.decl(s2d(l)),calc.SEC); } /** Wrapper für {@link Mundan#decl(double,double) Deklination aus ekliptikaler Länge und Breite} */ public String decl(String l, String b) { return dms(m.decl(s2d(l),s2d(b)),calc.SEC); } /** Getter für {@link Mundan#ee() Ekliptikschiefe} */ public String ee() { return dms(m.ee(),calc.SEC); } /** Getter für {@link Mundan#getHsys() Häusersystem} */ public byte getHsys() { return m.getHsys(); } /** Getter für {@link Mundan#getLatitude() geographische Breite} */ public String getLatitude() { return dms(m.getLatitude(),calc.SEC); } /** Getter für {@link Mundan#getSiderealTime() Sternzeit} */ public String getSiderealTime() { return dms(m.getSiderealTime()/15,calc.TIME+calc.SEC); } /** Wrapper für {@link Mundan#hauslaenge(double) Ekliptiklänge zu gegebener mundaner Position} (Häuserproblem). */ public String hauslaenge(String mp) { return dms(m.hauslaenge(s2d(mp)),calc.ECL+calc.SEC); } /** Wrapper für {@link Mundan#hauslaenge(double,double) Ekliptiklänge zu gegebener mundaner Position und RAMC} (Häuserproblem). */ public String hauslaenge(String mp, String st) { return dms(m.hauslaenge(s2d(mp),s2d(st)),calc.ECL+calc.SEC); } /** Wrapper für {@link Mundan#hb(double,boolean) Halben Tag- oder Nachtbogen} */ public String hb(String d, String visible) { return dms(m.hb(s2d(d), toBoolean(visible)),calc.SEC); } /** Wrapper für {@link Mundan#isVisible(double,double) Position über dem Horizont} */ public boolean isVisible(String a, String d) { return m.isVisible(s2d(a),s2d(d)); } /** Wrapper für {@link Mundan#mclaenge(double) Ekliptiklänge zur Rektaszension} */ public String mclaenge(String a) { return dms(m.mclaenge(s2d(a)),calc.ECL+calc.SEC); } /** Wrapper für {@link Mundan#md(double) Meridionaldistanz aus Rektaszension} */ public String md(String a) { return dms(m.md(s2d(a)),calc.ECL+calc.SEC); } /** Wrapper für {@link Mundan#md(double,boolean) Tag- oder Nacht-Meridionaldistanz aus Rektaszension} */ public String md(String a, String visible) { return dms(m.md(s2d(a),toBoolean(visible)),calc.SEC); } /** Wrapper für {@link Mundan#munpos(double,double,StringBuffer) Mundanposition aus Länge und Breite} */ public String munpos(String l, String b) { StringBuffer serr = new StringBuffer(); String s = dms(m.munpos(s2d(l), s2d(b),serr),calc.SEC); if (serr.length() > 0) System.out.println(serr); return s; } /** Wrapper für {@link Mundan#munpos(double,double,StringBuffer) Mundanposition aus Länge} */ public String munpos(String l) { StringBuffer serr = new StringBuffer(); String s = dms(m.munpos(s2d(l), 0d,serr),calc.SEC); if (serr.length() > 0) System.out.println(serr); return s; } /** Wrapper für {@link Mundan#oa(double,double) Schräge Aufsteigung aus Rektaszension und Deklination} */ public String oa(String a, String d) { return dms(m.oa(s2d(a),s2d(d)),calc.SEC); } /** Wrapper für {@link Mundan#oa(double,double,double) Schräge Aufsteigung aus Rektaszension, Deklination und Polhöhe} */ public String oa(String a, String d, String pol) { return dms(m.oa(s2d(a),s2d(d),s2d(pol)),calc.SEC); } /** Wrapper für {@link Mundan#oaasc(double) Schräge Aufsteigung aus Ekliptiklänge} */ public String oaasc(String l) { return dms(m.oaasc(s2d(l)),calc.SEC); } /** Wrapper für {@link Mundan#ra(double,double) Gerade Aufsteigung aus Ekliptiklänge und -breite} */ public String ra(String l, String b) { return dms(m.ra(s2d(l),s2d(b)),calc.SEC); } /** Wrapper für {@link Mundan#radir(double,double) RA zu vorgegebener Deklination und Mundanposition} */ public String radir(String d, String mp) { return dms(m.radir(s2d(d),s2d(mp)),calc.SEC); } /** Wrapper für {@link Mundan#ramc(double) RA zur Ekliptiklänge} */ public String ramc(String l) { return dms(m.ramc(s2d(l)),calc.SEC); } /** Getter für {@link Mundan#getSiderealTime() Sternzeit im Gradmass (RAMC)} */ public String ramc() { return dms(m.getSiderealTime(),calc.SEC); } /** Setter für {@link Mundan#setEE(double) Ekliptikschiefe} */ public void setEE(String ee) { m.setEE(s2d(ee)); } /** Setter für {@link Mundan#setHsys(byte) Häusersystem} */ public void setHsys(String hsys) { m.setHsys((byte) toInt(hsys)); } /** Setter für {@link Mundan#setLatitude(double) geographische Breite} */ public void setLatitude(String lat) { m.setLatitude(s2d(lat)); } /** Setter für {@link Mundan#setSiderealTime(double) Sternzeit} */ public void setSiderealTime(String st) { m.setSiderealTime(s2d(st)); } }