DBFunktionen.java
001 /*
002  * Created on 16.02.2004
003  */
004 package de.fub.tip.datenbank;
005 
006 import java.sql.*;
007 import javax.sql.DataSource;
008 
009 import org.apache.log4j.Logger;
010 
011 import de.fub.tip.datenanzeige.Koordinate;
012 import de.fub.tip.datenanzeige.ormapper.*;
013 /**
014  * Sinn: kapselt Zugriffe auf die Datenbank dahingehend,
015  * dass jede Funktion eine Connection aus dem Struts-DB-
016  * Verbindungspool übernimmt und dann die entsprechende Funktion ausführt.
017  <br>
018  * Zusätzlich finden sich hier POSTGIS-erleichternde Funktionen, 
019  * die häufig benutzt werden.<br>
020  
021  @author hirsch, 16.02.2004
022  @version 2004-06-10
023  * $Id: DBFunktionen.java,v 1.16 2004/06/10 09:28:09 hirsch Exp $
024  
025  */
026 public class DBFunktionen {
027   /** Logger zur Fehlersuche */
028   private static Logger logger = Logger.getLogger(DBFunktionen.class);
029 
030   /**
031    * prüft, ob ein Benutzer eine Sehenswürdigkeit bereits gesehen hat 
032    * oder nicht.<br>
033    * Dies bedeutet nur, dass der Benutzer bereits an diesem Ort war!
034    
035    @param user angemeldeter Benutzer
036    @param loc aktueller Standort
037    @param dataSource Datenbankverbindung zur Abfrage
038    
039    @return true - wenn Benutzer schonmal hier war, sonst false
040    */
041   public static Boolean alreadyVisited(UserdataVO user, 
042     LocationVO loc, DataSource dataSource) {
043 
044   Boolean ergebnis = new Boolean(false);
045   PreparedStatement prepStat = null;
046   Connection con = null;
047 
048   // eigentlich wird nur geguckt, ob die Abfrage ein Tupel zurückgibt,
049   // was der Fall ist, wenn ein LocationEvent zum übergeben Tupel aus
050   // (user, Location) existiert
051    String sql = "SELECT leid FROM locationevent " +
052      "WHERE udid= ? " +
053      "AND location && GeometryFromText( ? ,-1) " +
054      "AND Distance(GeometryFromText( ? ,-1), location) < ?";
055 
056    try {
057     con = dataSource.getConnection();
058 
059     prepStat = con.prepareStatement(sql);
060     prepStat.setInt(1, user.getId().intValue());
061     prepStat.setString(2, DBFunktionen.getBox(loc.getLocation()));
062     prepStat.setString(3, DBFunktionen.getPoint(loc.getLocation()));
063     prepStat.setDouble(4, Koordinate.getDistance());
064 
065     ResultSet rs = prepStat.executeQuery();
066     if(rs!=null && rs.next()) {
067       ergebnis = new Boolean(true);
068     // end if
069 
070    catch (SQLException e) {
071      logger.error("DBFunktionen.alreadyVisited(): Fehler - " + e + ", "+
072        e.getLocalizedMessage());
073 
074    catch(Exception e) {
075      // Damit auf keinen Fall auf den Webseiten Fehler angezeigt werden,
076      // die durch das Logging verursacht wurden ....
077      logger.error("DBFunktionen.alreadyVisited(): Problem - "+e +", "
078        e.getLocalizedMessage());
079        
080    // end of try
081     
082    // Datenbankverbindung schliessen
083    finally {
084      try {
085        if(con!=nullcon.close();
086        logger.debug("DBFunktionen.alreadyVisited(): " +
087          "DB-Con geschlossen.");
088      catch (SQLException e1) {
089        logger.debug("DBFunktionen.alreadyVisited(): " + e1);
090        logger.debug("DBFunktionen.alreadyVisited(): " +
091          "Fehler beim Schliessen der DB-Con: " + e1.getLocalizedMessage());
092      // end of catch
093    // end of finally
094 
095   return ergebnis;
096   // end of alreadyVisited
097 
098   /**
099    * Damit man nicht standardmässig die int-Werte der Klasse Geometry des
100    * Postgis-Paketes benutzen muss, <br>soll diese Methode eine
101    * englische Repräsentation des ganzen zurückliefern ....
102    
103    @see org.postgis.Geometry
104    
105    @param value interne Darstellung des Typs
106    @return geografischer Typ als String-Wort
107    */
108   public static String decodeGeoType(int value) {
109     switch(value) {
110       case 1return "POINT";
111       case 2return "LINESTRING";
112       case 3return "POLYGON";
113       case 4return "MULTIPOINT";
114       case 5return "MULTILINESTRING";
115       case 6return "MULTIPOLYGON";
116       case 7return "GEOMETRYCOLLECTION";
117       defaultreturn "unknown";
118     // end of switch
119   // end of decodeGeoType
120   
121   /**
122    * Laut Postgresql hätte man eigentlich 'box3d(usw.)' zurückgeben müssen.
123    * Dann gibt es aber Probleme mit dem Parsen 
124    * des <code>PreparedStatement</code>.
125    
126    * So geht es jetzt:
127    <ol>
128    <li>keine ?-Zeichen in ' einhüllen!</li>
129    <li>keine Parameterinhalte maskieren</li>
130    <li><code>prepStatement.setString(nr, inhalt)</code> benutzen und 
131    <code>inhalt</code> durch eine eigene Funktion erstellen lassen <br>
132    * (Dank an Hendrik Steller, 2004-03-22)</li>
133    </ol>
134    
135    @param x Koordinate x
136    @param y Koordinate y
137    @param x1 Koordinate x1
138    @param y1 Koordinate y1
139    
140    @return für <code>PreparedStatement</code> umgewandelte Postgres/
141    * Postgis-box-Darstellung
142    */
143   public static String getBox(double x, double y, double x1, double y1) {
144     // Vergleich zu Katjas alter Version:     
145     // x1=x-distance;   = Koordinate.xLinks
146     // x2=x+distance;  = Koordinate.xRechts
147     // y1=y-distance;  = Koordinate.yLinks
148     // y2=y+distance;  = Koordinate.yRechts
149     // dann: BOX3D("+x1+" "+y1+", "+x2+" "+y2+ ..
150     return "BOX3D(" + x + " " + y + "," + x1 + " " + y1+ ")";
151   // end of getBox
152   
153   /**
154    * wandelt Koordinate in PostGIS-box3d um 
155    @param k Koordinate
156    @return für <code>PreparedStatement</code> umgewandelte Postgres/
157    * Postgis-box-Darstellung
158    */
159   public static String getBox(Koordinate k) {
160     k.calculateArea();
161     return "BOX3D(" + k.getXLinks() " " + k.getXRechts() "," 
162       k.getYLinks() " " + k.getYRechts()")";
163   // end of getBox
164 
165   /**
166    * siehe getBox()
167    
168    @param x Koordinate x
169    @param y Koordinate y
170    @return für <code>PreparedStatement</code> umgewandelte Postgres/
171    * Postgis-punkt-Darstellung
172    */
173   public static String getPoint(double x, double y) {
174     // Vergleich zu Katjas alter Version:     
175     // dann: POINT ("+x+" "+y+...
176     return "POINT(" + x + " " + y + ")";
177   // end of getPoint
178 
179   /**
180    * wandelt Koordinate in PostGIS-Darstellung um 
181    @param k Koordinate
182    @return für <code>PreparedStatement</code> umgewandelte Postgres/
183    * Postgis-punkt-Darstellung
184    */
185   public static String getPoint(Koordinate k) {
186     k.calculateArea();
187     return "POINT(" + k.getX() " " + k.getY() ")";
188   // end of getPoint
189 
190   /**
191    * maskiert den übergebenen String nach SQL-Syntax mit einem %...% für
192    * die Benutzung des LIKE-Konstrukts.
193    *  
194    @param sql SQL-Ersetzung
195    @return für <code>PreparedStatement</code> 
196    * umgewandelte SQL-LIKE-Darstellung
197    */
198   public static String getSQLLike(String sql) {
199     return "%" + sql + "%";
200   // end of getSQLLike
201 
202 // end of class