Project

General

Profile

1
/**
2
 *  '$RCSfile$'
3
 *  Copyright: 2000 Regents of the University of California and the
4
 *              National Center for Ecological Analysis and Synthesis
5
 *
6
 *   '$Author: tao $'
7
 *     '$Date: 2003-09-02 17:01:21 -0700 (Tue, 02 Sep 2003) $'
8
 * '$Revision: 1809 $'
9
 *
10
 * This program is free software; you can redistribute it and/or modify
11
 * it under the terms of the GNU General Public License as published by
12
 * the Free Software Foundation; either version 2 of the License, or
13
 * (at your option) any later version.
14
 *
15
 * This program is distributed in the hope that it will be useful,
16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
 * GNU General Public License for more details.
19
 *
20
 * You should have received a copy of the GNU General Public License
21
 * along with this program; if not, write to the Free Software
22
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
23
 */
24

    
25
package edu.ucsb.nceas.metacat.stringclient.impl;
26

    
27
import java.io.BufferedReader;
28
import java.io.InputStream;
29
import java.io.InputStreamReader;
30
import java.io.PushbackReader;
31
import java.io.IOException;
32
import java.io.StringWriter;
33
import java.io.Reader;
34
import java.net.URL;
35
import java.util.Properties;
36

    
37
import edu.ucsb.nceas.utilities.HttpMessage;
38
import edu.ucsb.nceas.utilities.IOUtil;
39

    
40
import org.globus.ogsa.impl.ogsi.GridServiceImpl;
41
import gt3tutorial.core.second.Metacat.MetacatPortType;
42
import java.rmi.RemoteException;
43

    
44
/**
45
 *  This interface provides methods for initializing and logging in to a 
46
 *  Metacat server, and then querying, reading, transforming, inserting, 
47
 *  updating and deleting documents from that server.
48
 */
49
public class MetacatStringImpl extends GridServiceImpl 
50
                               implements MetacatPortType
51
{
52
    /** The URL string for the metacat server */
53
    private String metacatUrl;
54

    
55
    /**
56
     *  Method used to log in to a metacat server. Implementations will need
57
     *  to cache a cookie value to make the session persistent.  Each time a
58
     *  call is made to one of the other methods (e.g., read), the cookie will
59
     *  need to be passed back to the metacat server along with the request.
60
     *
61
     *  @param username   the username of the user, like an LDAP DN
62
     *  @param password   the password for that user for authentication
63
     */
64
    public void login(String username, String password) throws RemoteException
65
        
66
    {
67
        Properties prop = new Properties();
68
        prop.put("action", "login");
69
        prop.put("qformat", "xml");
70
        prop.put("username", username);
71
        prop.put("password", password);
72

    
73
        String response = null;
74
        try {
75
            response = sendDataForString(prop);
76
        } catch (Exception e) {
77
            throw new RemoteException(e.getMessage());
78
        }
79

    
80
        if (response.indexOf("<login>") == -1) {
81
            HttpMessage.setCookie(null);
82
            throw new RemoteException(response);
83
        }
84
    }
85

    
86
    /**
87
     *  Method used to log out a metacat server. When Metacat server will end
88
     *  the session when this call is invoken.
89
     *
90
     *  @throws MetacatInaccessibleException when the metacat server can not be
91
     *                                    reached or does not respond
92
     */
93
    public void logout() throws RemoteException
94
    {
95
        Properties prop = new Properties();
96
        prop.put("action", "logout");
97
        prop.put("qformat", "xml"); 
98
       
99
        String response = null;
100
        try {
101
            response = sendDataForString(prop);
102
        } catch (Exception e) {
103
            throw new RemoteException(e.getMessage());
104
        }
105
        
106
        if (response.indexOf("<logout>") == -1) {
107
            throw new RemoteException(response);
108
        }
109
    }
110
    
111
    
112
    /**
113
     * Read an XML document from the metacat server session, accessed by docid,
114
     * and returned as a String.
115
     *
116
     * @param docid the identifier of the document to be read
117
     * @return a String for accessing the document
118
     */
119
    public String read(String docid) throws RemoteException
120
    {
121
        Properties prop = new Properties();
122
        prop.put("action", "read");
123
        prop.put("qformat", "xml");
124
        prop.put("docid", docid);
125

    
126
        InputStream response = null;
127
        try {
128
            response = sendDataForString(prop);
129
        } catch (Exception e) {
130
            throw new RemoteException(e.getMessage());
131
        }
132
        if (response != null && response.indexOf("<error>") != -1) {
133
                if (response.indexOf("does not have permission") != -1) {
134
                    throw new RemoteException(response);
135
                } else {
136
                    throw new RemoteException(response);
137
                }
138
         }
139
     
140
        return response;
141
    }
142

    
143
    /**
144
     * Query the metacat document store with the given metacat-compatible 
145
     * query document, and return the result set as a Reader.
146
     *
147
     * @param xmlQuery a string for accessing the XML version of the query
148
     * @return a string for accessing the result set
149
     */
150
    public String query(String xmlQuery) throws RemoteException 
151
    {
152
        String query = xmlQuery;
153
      
154
        //set up properties
155
        Properties prop = new Properties();
156
        prop.put("action", "squery");
157
        prop.put("qformat", "xml");
158
        prop.put("query", query);
159
        
160
        String response = null;
161
        try {
162
            response = sendDataForString(pop);
163
          
164
        } catch (Exception e) {
165
            throw new RemoteException(e.getMessage());
166
        }
167
       
168
        return response;
169
    }
170

    
171
    /**
172
     * Insert an XML document into the repository.
173
     *
174
     * @param docid the docid to insert the document
175
     * @param xmlDocument a Reader for accessing the XML document to be inserted
176
     * @param schema a Reader for accessing the DTD or XML Schema for 
177
     *               the document
178
     * @return the metacat response message
179
     */
180
    public String insert(String docid, String xmlDocument, String schema)
181
        throws RemoteException
182
    {
183
        String doctext = xmlDocument;
184
        String schematext = schema;
185
     
186
     //set up properties
187
        Properties prop = new Properties();
188
        prop.put("action", "insert");
189
        prop.put("docid", docid);
190
        prop.put("doctext", doctext);
191
        if (schematext != null) {
192
            prop.put("dtdtext", schematext);
193
        }
194
        
195
        String response = null;
196
        try {
197
            response = sendDataForString(prop);
198
        } catch (Exception e) {
199
            throw new RemoteException(e.getMessage());
200
        }
201

    
202
        // Check for an error condition
203
        if (response.indexOf("<error>") != -1) {
204
            if (response.indexOf("does not have permission") != -1) {
205
                throw new RemoteException(response);
206
            } else {
207
                throw new RemoteException(response);
208
            }
209
        }
210

    
211
        return response;
212
    }
213

    
214
    /**
215
     * Update an XML document in the repository.
216
     *
217
     * @param docid the docid to update
218
     * @param xmlDocument a Reader for accessing the XML text to be updated
219
     * @param schema a Reader for accessing the DTD or XML Schema for 
220
     *               the document
221
     * @return the metacat response message
222
     */
223
    public String update(String docid, String xmlDocument, String schema)
224
        throws RemoteException
225
    {
226
        String doctext = xmlDocument;
227
        String schematext = Schema;
228
      
229

    
230
        //set up properties
231
        Properties prop = new Properties();
232
        prop.put("action", "update");
233
        prop.put("docid", docid);
234
        prop.put("doctext", doctext);
235
        if (schematext != null) {
236
            prop.put("dtdtext", schematext);
237
        }
238
        
239
        String response = null;
240
        try {
241
            response = sendDataForString(prop);
242
        } catch (Exception e) {
243
            throw new RemoteException(e.getMessage());
244
        }
245

    
246
        // Check for an error condition
247
        if (response.indexOf("<error>") != -1) {
248
            if (response.indexOf("does not have permission") != -1) {
249
                throw new RemoteException(response);
250
            } else {
251
                throw new RemoteException(response);
252
            }
253
        }
254

    
255
        return response;
256
    }
257

    
258
    /**
259
     * Delete an XML document in the repository.
260
     *
261
     * @param docid the docid to delete
262
     * @return the metacat response message
263
     */
264
    public String delete(String docid) throws RemoteException
265
    {
266
        //set up properties
267
        Properties prop = new Properties();
268
        prop.put("action", "delete");
269
        prop.put("docid", docid);
270
        
271
        String response = null;
272
        try {
273
            response = sendDataForString(prop);
274
        } catch (Exception e) {
275
            throw new RemoteException(e.getMessage());
276
        }
277

    
278
        // Check for an error condition
279
        if (response.indexOf("<error>") != -1) {
280
            if (response.indexOf("does not have permission") != -1) {
281
                throw new RemoteException(response);
282
            } else {
283
                throw new RemoteException(response);
284
            }
285
        }
286

    
287
        return response;
288
    }
289

    
290
 
291
    /************************************************************************
292
     * PRIVATE METHODS
293
     ************************************************************************/
294

    
295
    /**
296
     * Send a request to metacat.
297
     *
298
     * @param prop the properties to be URL encoded and sent
299
     */
300
    synchronized private InputStream sendDataOnce(Properties prop) 
301
        throws Exception
302
    {
303
        InputStream returnStream = null;
304
        URL url = new URL(metacatUrl);
305
        HttpMessage msg = new HttpMessage(url);
306
        returnStream = msg.sendPostData(prop);
307
        return returnStream;
308
    }
309

    
310
    /**
311
     * Send a request to Metacat
312
     *
313
     * @param prop  the properties to be sent to Metacat
314
     * @return      InputStream as returned by Metacat
315
     */
316
    synchronized private InputStream sendData(Properties prop) throws Exception
317
    {   
318
        InputStream returnStream = null;
319

    
320
        /*
321
            Note:  The reason that there are three try statements all executing
322
            the same code is that there is a problem with the initial connection
323
            using the HTTPClient protocol handler.  These try statements make 
324
            sure that a connection is made because it gives each connection a 
325
            2nd and 3rd chance to work before throwing an error.
326
            THIS IS A TOTAL HACK.  THIS NEEDS TO BE LOOKED INTO AFTER THE BETA1
327
            RELEASE OF MORPHO!!!  cwb (7/24/01)
328
          */
329
        try {
330
           return sendDataOnce(prop);
331
        } catch (Exception e) {
332
            try {
333
                return sendDataOnce(prop);
334
            } catch (Exception e2) {
335
                try {
336
                    return sendDataOnce(prop);
337
                } catch (Exception e3) {
338
                    System.err.println(
339
                            "Failed to send data to metacat 3 times.");
340
                    throw e3;
341
                }
342
            }
343
        }
344
    }
345

    
346
    /**
347
     * Send a request to Metacat
348
     *
349
     * @param prop  the properties to be sent to Metacat
350
     * @return      a string as returned by Metacat
351
     */
352
    synchronized private String sendDataForString(Properties prop) 
353
        throws Exception
354
    {
355
        String response = null;
356

    
357
        try {
358
            InputStreamReader returnStream =
359
                    new InputStreamReader(sendData(prop));
360
            StringWriter sw = new StringWriter();
361
            int len;
362
            char[] characters = new char[512];
363
            while ((len = returnStream.read(characters, 0, 512)) != -1) {
364
                sw.write(characters, 0, len);
365
            }
366
            returnStream.close();
367
            response = sw.toString();
368
            sw.close();
369
        } catch (Exception e) {
370
            throw e;
371
        }
372
        return response;
373
    }
374
}
(2-2/2)