Project

General

Profile

« Previous | Next » 

Revision 1391

Added by Jing Tao about 22 years ago

New class to handle ingore user specification for schema location, upload new schemalocation to metacat and register namespace and schema location in xml_catalog table.

View differences:

src/edu/ucsb/nceas/metacat/SchemaLocationResolver.java
1
/**
2
 *  '$RCSfile$'
3
 *    Purpose: A Class that implements org.xml.sax.EntityResolver interface
4
 *             for resolving external entities
5
 *  Copyright: 2000 Regents of the University of California and the
6
 *             National Center for Ecological Analysis and Synthesis
7
 *    Authors: Jivka Bojilova, Matt Jones
8
 *    Release: @release@
9
 *
10
 *   '$Author$'
11
 *     '$Date$'
12
 * '$Revision$'
13
 *
14
 * This program is free software; you can redistribute it and/or modify
15
 * it under the terms of the GNU General Public License as published by
16
 * the Free Software Foundation; either version 2 of the License, or
17
 * (at your option) any later version.
18
 *
19
 * This program is distributed in the hope that it will be useful,
20
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22
 * GNU General Public License for more details.
23
 *
24
 * You should have received a copy of the GNU General Public License
25
 * along with this program; if not, write to the Free Software
26
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
27
 */
28

  
29
package edu.ucsb.nceas.metacat;
30

  
31

  
32
import java.sql.*;
33
import java.io.File;
34
import java.io.Reader;
35
import java.io.BufferedReader;
36
import java.io.BufferedInputStream;
37
import java.io.FileWriter;
38
import java.io.BufferedWriter;
39
import java.io.InputStream;
40
import java.io.IOException;
41
import java.net.URL;
42
import java.net.URLConnection;
43
import java.net.MalformedURLException;
44
import java.util.Vector;
45

  
46
/**
47
 * A database aware Class to handle schema location. If namespace is in the
48
 * xml_catalog table (public_id), the schema location specified in xml document
49
 * will be ignored by parser setting external schema location. If the
50
 * name space is not in the table, it will be download to metacat and register
51
 * in table
52
 */
53
public class SchemaLocationResolver
54
{
55
  
56
  private String nameSpace = null; //public id
57
  private String schemaLocation = null; // system id
58
  private Vector nameSpaceList = new Vector();// name space in the table
59
  private String nameSpaceAndLocationString = null; // the parameter will be set
60
                                              // in external property in parser
61
  //private String schemaFileName = null;
62
  // constant
63
  private String SCHEMATYPE ="Schema"; 
64
  private String WHITESPACESTRING =" ";                                                         
65

  
66
  public SchemaLocationResolver()
67
  {
68
    createNameSpaceAndLocationStringFromDB();
69
  }
70
  /**
71
   * Construct an instance of the SchemaLocationResolver class
72
   *
73
   * @param  myNameSpaceAndLocation it is come from xsi:schemaLocation=
74
   *         "namespace location"
75
   */
76
  public SchemaLocationResolver(String myNameSpaceAndLocation)
77
  {
78
    parse(myNameSpaceAndLocation);
79
  }
80
  
81
  /**
82
   * A method to get nameSpaceAndLocationString
83
   */
84
  public String getNameSpaceAndLocationString()
85
  {
86
    MetaCatUtil.debugMessage("namespace and location list is: " +
87
                             nameSpaceAndLocationString, 30);
88
    return nameSpaceAndLocationString;
89
  }
90
  
91
  /**
92
   * When got a name space, check if it is in the database, if it is do nothing
93
   * else upload it to metacat to store it and register it in catalog table
94
   */
95
  public void resolveNameSpace ()
96
  {
97
    //get name space lists
98
    createNameSpaceListFromDB();
99
  
100
    // if name space is not in table
101
    if (nameSpace !=null && schemaLocation != null &&
102
        !nameSpaceList.contains(nameSpace))
103
    {
104
       try
105
       {
106
        
107
        // upload schema into metacat
108
        InputStream in = DBEntityResolver.checkURLConnection(schemaLocation);
109
       
110
        String newURLInMetacat = uploadSchemaFromURL(in);
111
       
112
        // reigister schema
113
        registerSchema(newURLInMetacat);
114
     
115
       }
116
       catch(Exception e)
117
       {
118
         MetaCatUtil.debugMessage("Error in SchemaLocation.resolveNameSpace" +
119
                                  e.getMessage(), 30);
120
       }
121
 
122
    }//if
123
 
124
  }
125

  
126
  /* This method will take look xml_catalog table and create a string look like
127
   * "namespace1 location namespacke2 location". This string will be set as 
128
   * a extenalschemalocation in SAX parser. Then when parser check the 
129
   * it will ignore the schema location specified by xml document
130
   */
131
  private void createNameSpaceAndLocationStringFromDB()
132
  {
133
    DBConnection conn = null;
134
    int serialNumber = -1;
135
    PreparedStatement pstmt = null;
136
    ResultSet result = null;
137
    String sql = "SELECT public_id, system_id FROM xml_catalog where " +
138
                 "entry_type ='" + SCHEMATYPE +"'";
139
    try 
140
    {
141
      //check out DBConnection
142
      conn=DBConnectionPool.getDBConnection("SchemaLocationResl.createName");
143
      serialNumber=conn.getCheckOutSerialNumber();
144
      pstmt = conn.prepareStatement(sql);
145
      pstmt.execute();
146
      result = pstmt.getResultSet();
147
      
148
      // Get string for namespace and location form DB
149
      boolean hasRow = result.next();
150
      StringBuffer buffer = new StringBuffer();
151
      boolean firstTime = true;
152
      while (hasRow)
153
      {
154
        String namespace = result.getString(1);
155
        String location  = result.getString(2);
156
        String pairOfNameSpaceAndLocation = namespace + WHITESPACESTRING 
157
                                            +location;
158
        if (!firstTime)
159
        {
160
          buffer.append(WHITESPACESTRING);
161
        }
162
        buffer.append(pairOfNameSpaceAndLocation);
163
        firstTime = false;
164
        hasRow = result.next();
165
        
166
      }
167
      // give the buffer to the string if buffer has something in it
168
      if (buffer.length() != 0)
169
      {
170
        nameSpaceAndLocationString = buffer.toString();
171
      }
172
      result.close();
173
      pstmt.close();
174
    } 
175
    catch (SQLException e) 
176
    {
177
      MetaCatUtil.debugMessage
178
                        ("schemaLocation.createNameSpaceAndLocationString: " + 
179
                         e.getMessage(), 30);
180
    }
181
    finally
182
    {
183
      try
184
      {
185
        pstmt.close();
186
      }//try
187
      catch (SQLException sqlE)
188
      {
189
        MetaCatUtil.debugMessage("Error in schema.createNameSpaceAndLocation "
190
                                    + sqlE.getMessage(), 30);
191
      }//catch
192
      DBConnectionPool.returnDBConnection(conn, serialNumber);
193
    }//finally
194
    
195

  
196
  }
197

  
198
  /* This method will take look xml_catalog table and create a name space
199
   * vector already in the table
200
   */
201
  private void createNameSpaceListFromDB()
202
  {
203
    DBConnection conn = null;
204
    int serialNumber = -1;
205
    PreparedStatement pstmt = null;
206
    ResultSet result = null;
207
    String sql = "SELECT public_id FROM xml_catalog where " +
208
                 "entry_type ='" + SCHEMATYPE +"'";
209
    try 
210
    {
211
      //check out DBConnection
212
      conn=DBConnectionPool.getDBConnection("SchemaLocationResl.createNameList");
213
      serialNumber=conn.getCheckOutSerialNumber();
214
      pstmt = conn.prepareStatement(sql);
215
      pstmt.execute();
216
      result = pstmt.getResultSet();
217
      
218
      // Get string for namespace form DB and store in the vector
219
      boolean hasRow = result.next();
220
      while (hasRow)
221
      {
222
        String namespace = result.getString(1);
223
        nameSpaceList.addElement(namespace);
224
        hasRow = result.next();
225
        
226
      }
227
      pstmt.close();
228
      result.close();
229
    } 
230
    catch (SQLException e) 
231
    {
232
      MetaCatUtil.debugMessage
233
                        ("schemaLocation.createNameSpaceList: " + 
234
                         e.getMessage(), 30);
235
    }
236
    finally
237
    {
238
      try
239
      {
240
        pstmt.close();
241
      }//try
242
      catch (SQLException sqlE)
243
      {
244
        MetaCatUtil.debugMessage("Error in schemaLocation.createNameSpaceList: "
245
                                    +sqlE.getMessage(), 30);
246
      }//catch
247
      DBConnectionPool.returnDBConnection(conn, serialNumber);
248
    }//finally
249
  
250
  }
251
  
252
   
253

  
254
  /**
255
   * Upload new Schema located at outside URL to Metacat file system
256
   */
257
  private String uploadSchemaFromURL(InputStream istream) throws Exception
258
  {
259
   
260
    String schemaPath = MetaCatUtil.getOption("schemaPath");
261
    String schemaURL = MetaCatUtil.getOption("schemaURL");
262

  
263
    // get filename from systemId
264
    String filename = schemaLocation;
265
  
266
    if (filename != null && !(filename.trim()).equals(""))
267
    {
268
      int slash = Math.max(filename.lastIndexOf('/'), filename.lastIndexOf('\\'));
269
      if ( slash > -1 ) 
270
      {
271
        filename = filename.substring(slash + 1);
272
      }
273
    }
274
    else
275
    {
276
      return null;
277
    }
278
    // writing schema text on Metacat file system as filename
279
    try {
280
      // create a buffering character-input stream
281
      // that uses a default-sized input buffer
282
      BufferedInputStream in = new BufferedInputStream(istream);
283

  
284
      // open file writer to write the input into it
285
      File f = new File(schemaPath, filename);
286
      synchronized (f) 
287
      {
288
        try 
289
        {
290
          if ( f.exists() ) 
291
          {
292
           throw new IOException("File already exist: " + f.getCanonicalFile());
293
          }
294
        } 
295
        catch (SecurityException se) 
296
        {
297
         // if a security manager exists,
298
          throw se;
299
       }
300
      // create a buffered character-output stream
301
      // that uses a default-sized output buffer
302
      FileWriter fw = new FileWriter(f);
303
      BufferedWriter out = new BufferedWriter(fw);
304

  
305
      // read the input and write into the file writer
306
      int inputByte;
307
      while ( (inputByte = in.read()) != -1 ) 
308
      {
309
        out.write(inputByte);
310
        //out.newLine(); //instead of out.write('\r\n');
311
      }
312

  
313
      // the input and the output streams must be closed
314
      in.close();
315
      out.flush();
316
      out.close();
317
      fw.close();
318
     } // end of synchronized
319
    } 
320
    catch (Exception e) 
321
    {
322
      throw new Exception
323
      ("shemaLocationResolver.uploadSchemaFromURL(): " + e.getMessage());
324
    } 
325
    MetaCatUtil.debugMessage("new schema location is: " + schemaURL + 
326
                              filename, 20);
327
    return  schemaURL + filename;
328
  }
329

  
330
  
331
  /*
332
   * Register new schema identified by @systemId in Metacat XML Catalog
333
   */
334
  private void registerSchema(String systemId )
335
  {
336
    // check systemid is not null
337
    if (systemId == null || nameSpace == null || (nameSpace.trim()).equals(""))
338
    {
339
     
340
      return;
341
    }
342
    
343
    DBConnection conn = null;
344
    int serialNumber = -1;
345
    PreparedStatement pstmt = null;
346
    String sql = "INSERT INTO xml_catalog " +
347
             "(entry_type, public_id, system_id) " +
348
             "VALUES ('" + SCHEMATYPE + "', ?, ?)";
349
    
350
 
351
    try 
352
    {
353
      //check out DBConnection
354
      conn=DBConnectionPool.getDBConnection("schemaLocation.registerSchema");
355
      serialNumber=conn.getCheckOutSerialNumber();
356
      pstmt = conn.prepareStatement(sql);
357
     
358
      // Bind the values to the query
359
      pstmt.setString(1, nameSpace);
360
      pstmt.setString(2, systemId);
361
      // Do the insertion
362
      pstmt.execute();
363
      pstmt.close();
364
    } 
365
    catch (SQLException e) 
366
    {
367
      MetaCatUtil.debugMessage
368
      ("SchemaLocation.egisterSchema(): " + e.getMessage(), 30);
369
    }
370
    finally
371
    {
372
      try
373
      {
374
        pstmt.close();
375
      }//try
376
      catch (SQLException sqlE)
377
      {
378
        MetaCatUtil.debugMessage("Error in SchemaLocation.egisterSchema(): "
379
                                    +sqlE.getMessage(), 30);
380
      }//catch
381
      DBConnectionPool.returnDBConnection(conn, serialNumber);
382
    }//finally
383

  
384
  }
385
  
386
  /*
387
   * A method to parse the value for xis:schemaLocation="namespace location"
388
   * and store the namespace in nameSpace and location in schemaLocaion
389
   */
390
  private void parse(String nameSpaceAndLocation)
391
  {
392
    // check the parameter
393
    if (nameSpaceAndLocation == null||(nameSpaceAndLocation.trim()).equals(""))
394
    {
395
      return;
396
    }
397
    //Get white space index (delimiter)
398
    int indexOfWhiteSpace = nameSpaceAndLocation.lastIndexOf(WHITESPACESTRING);
399
    if (indexOfWhiteSpace != -1)
400
    {
401
      // before white space is namespace
402
      nameSpace = nameSpaceAndLocation.substring(0,indexOfWhiteSpace);
403
      // after white sapce is schema location
404
      schemaLocation = nameSpaceAndLocation.substring(indexOfWhiteSpace+1);
405
      // Gebug message
406
      MetaCatUtil.debugMessage("Namespace after parsing: " + nameSpace, 30);
407
      MetaCatUtil.debugMessage("Location after parsing: " + schemaLocation, 30);
408
    } 
409
  }
410
  
411
  public static void main(String[] argus)
412
  {
413
     try
414
     {
415
       DBConnectionPool pool = DBConnectionPool.getInstance();
416
       // Print out a empty schema list
417
       SchemaLocationResolver schema = new SchemaLocationResolver();
418
       MetaCatUtil.debugMessage("Namespace and Location String: "+ 
419
                                schema.getNameSpaceAndLocationString(), 20);
420
       // input a schemalocation
421
       SchemaLocationResolver schema2 = new SchemaLocationResolver(
422
                                        "eml://ecoinformatics.org/eml-2.0.0 " +
423
                                "http://dev.nceas.ucsb.edu/tao/schema/eml.xsd");
424
       schema2.resolveNameSpace();
425
       // input a wrong name space location
426
       SchemaLocationResolver schema3 = new SchemaLocationResolver(
427
                                        "http://www.xml-cml.org/schema/stmml " +
428
                              "http://dev.nceas.ucsb.edu/tao/schema/stmml.xsd");
429
       schema3.resolveNameSpace();
430
       // print out new schema list in db
431
       SchemaLocationResolver schema4 = new SchemaLocationResolver();
432
       MetaCatUtil.debugMessage("Namespace and Location String: "+ 
433
                                schema4.getNameSpaceAndLocationString(), 20);
434
     }
435
     catch(Exception e)
436
     {
437
       MetaCatUtil.debugMessage("erorr in Schemalocation.main: " + 
438
                                e.getMessage(), 30);
439
     }
440
  }
441
}
0 442

  

Also available in: Unified diff