001    package hep.aida.ref.sql;
002    
003    // Log4J
004    import org.apache.log4j.Logger;
005    
006    /** <code>AIDAURL</code> manages information about SQL URL.
007      * <p><font color="#880088">
008      * <pre>
009      * $Log: AIDAURL.java,v $
010      * Revision 1.19  2008/07/25 13:25:02  hrivnac
011      * oracle schema for tags supported improved
012      *
013      * Revision 1.18  2007/05/23 16:38:43  hrivnac
014      * logical connections for Plotter; better UML
015      *
016      * Revision 1.17  2007/05/22 23:33:20  hrivnac
017      * Plotter uses real arguments parsing
018      *
019      * Revision 1.16  2006/12/13 16:38:51  hrivnac
020      * derby works in JAS3 Plugin
021      *
022      * Revision 1.15  2006/12/13 15:39:29  hrivnac
023      * derby url modified
024      *
025      * Revision 1.14  2006/12/12 15:21:42  hrivnac
026      * McKoi replaced with Derby; uppercase-only dbs handled better; moving to JAS 0.8.3
027      *
028      * Revision 1.13  2006/11/10 17:40:02  hrivnac
029      * WebService updated, long-format Oracle URL allowed, complete db not parsed if only table requested (speed)
030      *
031      * Revision 1.12  2005/09/28 16:21:06  hrivnac
032      * code cleaning
033      *
034      * Revision 1.11  2005/01/25 16:45:03  hrivnac
035      * Adding rows uses PreparedStatement
036      *
037      * Revision 1.10  2004/12/08 10:15:38  hrivnac
038      * ITree created with sensible name for Oracle
039      *
040      * Revision 1.9  2004/10/22 15:32:59  hrivnac
041      * cleaned
042      *
043      * Revision 1.8  2004/10/22 14:22:44  hrivnac
044      * properties loading refactored
045      *
046      * Revision 1.7  2004/10/08 15:22:33  hrivnac
047      * JAS3 plugin works
048      *
049      * Revision 1.6  2004/09/07 14:03:42  hrivnac
050      * AIDAURL supports with/without tables
051      *
052      * Revision 1.5  2004/07/06 14:24:50  hrivnac
053      * support for Oracle
054      *
055      * Revision 1.4  2004/05/22 15:12:59  hrivnac
056      * class id reformated
057      *
058      * Revision 1.3  2004/04/14 15:34:28  hrivnac
059      * changes required by ColMan
060      *
061      * Revision 1.2  2004/04/14 13:39:46  hrivnac
062      * 1.5 warnings fixed
063      *
064      * Revision 1.1  2004/04/13 15:45:54  hrivnac
065      * AIDA URL introduced
066      *
067      * </pre>
068      * </font></p>
069      * @opt attributes
070      * @opt operations
071      * @opt types
072      * @opt visibility
073      * @version $Id: AIDAURL.java,v 1.19 2008/07/25 13:25:02 hrivnac Exp $
074      * @author <a href="mailto:Julius.Hrivnac@cern.ch">J.Hrivnac</a> */
075    public class AIDAURL {
076    
077      /** Create from String url.
078        * @param url    The String url,
079        *               it should have following form:
080        *               <ul>
081        *               <li><code>&lt;file&gt;.aida[/&lt;table&gt;]</code></li>
082        *               <li><code>&lt;file&gt;.root[/&lt;table&gt;]</code></li>
083        *               <li><code>jdbc:[mysql|postgresql]://&lt;host&gt;/&lt;db&gt;[/&lt;table&gt;]</code></li>
084        *               <li><code>jdbc:derby:&lt;db&gt;()[/&lt;table&gt;]</code></li>
085        *               <li><code>jdbc:oracle:thin:@&lt;host&gt;:&lt;port&gt;:&lt;sid&gt;[/&lt;table&gt;]</code></li>
086        *               </ul>
087        * @param schema The schema of the database.
088        * @throws IllegalArgumentException if url doesn't describe AIDA URL. */
089      public AIDAURL(String url,
090                     String schema) throws IllegalArgumentException {
091        _url    = url;
092        _schema = schema;
093        if (url.contains(".aida")) {
094          _storeType = "xml";
095          parseName(url);
096          }
097        else if (url.contains(".root")) {
098          _storeType = "root";
099          parseName(url);
100          }
101        else if (url.contains("jdbc:")) {
102          _storeType = "sql";
103          parseDBName();
104          }
105        else {
106          throw new IllegalArgumentException("Can't interpret URL " + url);
107          }
108        }
109    
110      /** Create from String url.
111        * @param url The String url,
112        *            it should have following form:
113        *            <ul>
114        *            <li><code>&lt;file&gt;.aida[/&lt;table&gt;]</code></li>
115        *            <li><code>&lt;file&gt;.root[/&lt;table&gt;]</code></li>
116        *            <li><code>jdbc:[mysql|postgresql]://&lt;host&gt;/&lt;db&gt;[/&lt;table&gt;]</code></li>
117        *            <li><code>jdbc:derby:&lt;db&gt;()[/&lt;table&gt;]</code></li>
118        *            <li><code>jdbc:oracle:thin:@&lt;host&gt;:&lt;port&gt;:&lt;sid&gt;[/&lt;table&gt;]</code></li>
119        *            </ul>
120        * @throws IllegalArgumentException if url doesn't describe AIDA URL. */
121      // TBD: refactor
122      public AIDAURL(String url) throws IllegalArgumentException {
123        _url    = url;
124        _schema = null;
125        if (url.contains(".aida")) {
126          _storeType = "xml";
127          parseName(url);
128          }
129        else if (url.contains(".root")) {
130          _storeType = "root";
131          parseName(url);
132          }
133        else if (url.contains("jdbc:")) {
134          _storeType = "sql";
135          parseDBName();
136          }
137        else {
138          throw new IllegalArgumentException("Can't interpret URL " + url);
139          }
140        }
141    
142      /** Analyse url to find information about database. */
143      private void parseDBName() {
144        // Remove jdbc:
145        int firstDDot = _url.indexOf(":");
146        String s = _url.substring(firstDDot + 1, _url.length());
147        // Get and remove <impl>:
148        int secondDDot = s.indexOf(":");
149        _protocol = s.substring(0, secondDDot);
150        s = s.substring(secondDDot + 1, s.length());
151        // jdbc:impl://host/db/table
152        int firstDSlash = s.indexOf("//");
153        if (firstDSlash > -1) {
154          s = s.substring(firstDSlash + 2, s.length());
155          int firstSlash = s.indexOf("/");
156          if (firstSlash > - 1) {
157            s = s.substring(firstSlash + 1, s.length());
158            }
159          }
160        // Get db, table
161        parseName(s);
162        }
163    
164      /** Divide url into database and table part. Table part may be
165        * null.
166        * @param url The full url. */
167      private void parseName(String url) {
168        if ("derby".equals(_protocol) || "sqlite".equals(_protocol)) {
169          int lastBracks = url.lastIndexOf("()");
170          if (lastBracks + 2 < url.length()) {
171            _table = url.substring(lastBracks + 3);
172            _db    = _url.substring(0, _url.indexOf(_table) - 3);
173            }
174          else {
175            _table = null;
176            _db    = _url.substring(0, _url.length() - 2);
177            }
178          }
179        else {
180          int lastSlash = url.lastIndexOf("/");
181          if (lastSlash > 0) {
182            _table = url.substring(lastSlash + 1);
183            _db    = _url.substring(0, _url.indexOf(_table) - 1);
184            }
185          else {
186            _table = null;
187            _db    = _url;
188            }
189          }
190        if (_db.contains("/")) {
191          _name = _db.substring(_db.lastIndexOf("/") + 1, _db.length());
192          }
193        else if (_db.contains(":")) {
194          _name = _db.substring(_db.lastIndexOf(":") + 1, _db.length());
195          }
196        else if (_db.contains(".")) {
197          _name = _db.substring(0, _db.indexOf("."));
198          }
199        else {
200          _name = _db;
201          }
202        if (_schema != null && _table != null) {
203          _table = _schema + "." + _table;
204          }
205        }
206    
207      /** Give the table (tuple) URL.
208        * @return The table (tuple) URL. */
209      public String url() {
210        return _url;
211        }
212    
213      /** Give the database URL or filename.
214        * @return The database URL or filename. */
215      public String db() {
216        return _db;
217        }
218    
219      /** Give the table (tuple) name.
220        * @return The table (tuple) name. */
221      public String table() {
222        if (_table == null) {
223          return null;
224          }
225        else {
226          return Implementation.supportsOnlyUpperCase(_protocol) ? _table.toUpperCase() : _table;
227          }
228        }
229    
230      /** Give the store type.
231        * @return The store type. */
232      public String storeType() {
233        return _storeType;
234        }
235    
236      /** Give the name.
237        * @return The name. */
238      public String name() {
239        return _name;
240        }
241    
242      /** Give the protocol name..
243        * @return The protocol name. */
244      public String protocol() {
245        return _protocol;
246        }
247    
248      public String toString() {
249        if (_schema != null) {
250          return _url + "/" + _schema + " [" + _storeType + "]";
251          }
252        return _url + " [" + _storeType + "]";
253        }
254      
255      private String _url;
256    
257      private String _schema;
258    
259      private String _db;
260    
261      private String _table;
262    
263      private String _name;
264    
265      private String _storeType;
266    
267      private String _protocol;
268    
269      /** Selftest. */
270      public static void main(String[] args) {
271        String[] urls = {"test.aida",
272                         "test.root",
273                         "jdbc:mysql://host:port/database",
274                         "jdbc:derby:dir/db()",
275                         "jdbc:sqlite:dir/db()",
276                         "jdbc:oracle:thin:@host.domain.xy:port:sid",
277                         "jdbc:oracle:thin:@(DESCRIPTION = ...)"};
278        String[] tbls = {"/table", ""};
279        String fullurl = null;
280        AIDAURL aidaurl = null;
281        String format = "%-50.50s %-45.45s %-10.10s %-10.10s %-10.10s %-10.10s%n";
282        System.out.printf(format, "url", "db", "table", "name", "storeType", "protocol");
283        System.out.println("==================================================");
284        for (String tbl : tbls) {
285          for (String url : urls) {
286            fullurl = url + tbl;
287            aidaurl = new AIDAURL(fullurl);
288            System.out.printf(format, fullurl, 
289                                      aidaurl.db(),
290                                      aidaurl.table(),
291                                      aidaurl.name() ,
292                                      aidaurl.storeType() ,
293                                      aidaurl.protocol());
294            }
295          }
296        }
297    
298      /** Logging . */
299      private static Logger log = Logger.getLogger(AIDAURL.class);
300    
301      }