Project

General

Profile

1
/**
2
 *  '$RCSfile: XSLTransform.java,v $'
3
 *  Copyright: 2003 Regents of the University of California and the
4
 *             National Center for Ecological Analysis and Synthesis
5
 *
6
 *   '$Author: jones $'
7
 *     '$Date: 2003/08/18 20:27:03 $'
8
 * '$Revision: 1.4 $'
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.util;
26

    
27
import java.io.*;
28
import java.sql.PreparedStatement;
29
import java.sql.ResultSet;
30
import java.sql.SQLException;
31
import java.text.SimpleDateFormat;
32
import java.util.Enumeration;
33
import java.util.Hashtable;
34
import java.util.Vector;
35

    
36
import org.apache.log4j.Logger;
37

    
38
import edu.ucsb.nceas.metacat.DocumentImpl;
39
import edu.ucsb.nceas.metacat.DocumentImplWrapper;
40
import edu.ucsb.nceas.metacat.McdbException;
41
import edu.ucsb.nceas.metacat.database.DBConnection;
42
import edu.ucsb.nceas.metacat.database.DBConnectionPool;
43
import edu.ucsb.nceas.metacat.properties.PropertyService;
44

    
45
import javax.xml.transform.TransformerFactory;
46
import javax.xml.transform.Transformer;
47
import javax.xml.transform.stream.StreamSource;
48
import javax.xml.transform.stream.StreamResult;
49
import javax.xml.transform.TransformerException;
50
import javax.xml.transform.TransformerConfigurationException;
51
import javax.xml.transform.URIResolver;
52
import org.ecoinformatics.eml.EMLParser;
53

    
54

    
55
/**
56
 * A Class that transforms older eml version to newer eml version utitlizing XSL style sheets. 
57
 */
58
public class EMLVersionsTransformer {
59
	
60
	private static org.apache.log4j.Logger logMetacat = Logger.getLogger(EMLVersionsTransformer.class);
61
	private static String eml210StyleFile = null;
62
	static{
63
		try
64
		{
65
			eml210StyleFile =PropertyService.getProperty("application.deployDir")+"/"+PropertyService
66
			.getProperty("application.context")+ "/style/common/eml201to210.xsl"; //eml201to210.xsl place
67
		}
68
		catch(Exception e)
69
		{
70
			logMetacat.warn("Couldn't get eml201to210.xsl stylesheet");
71
		}
72
	}
73
	private static String DOT = ".";
74
	private static int CAP = 100000; // How many documents you want to transform.
75

    
76
    /**
77
     * Public constructor because all methods are static and do not need 
78
     * an instance.
79
     */
80
    public EMLVersionsTransformer() 
81
    {
82
    	
83
    }
84
    
85
    /**
86
     * Method to upgrade old versions of eml to new version
87
     */
88
    public void upgrade()
89
    {
90
    	upgradeEML200ToEML210();
91
    }
92
    
93
    /*
94
     * Upgrade every eml200 or eml210 documents into eml210
95
     */
96
    private  void upgradeEML200ToEML210()
97
    {
98
    	Vector list = getEML2DocList();
99
    	if(list != null)
100
    	{
101
    		// Choose the smaller value between the size of vector and CAP
102
    		int size = list.size();
103
    		if (size > CAP)
104
    		{
105
    			size = CAP;
106
    		}
107
    		for(int i=0; i<size; i++)
108
    		{
109
    			OwnerAndDocid pair = (OwnerAndDocid)list.elementAt(i);
110
    			String docid = pair.getDocid();
111
    			String owner = pair.getOwner();
112
    			try
113
    			{
114
    				handleSingleEML200Document(docid, owner);
115
    				try
116
    				{
117
    					Thread.sleep(5000);
118
    				}
119
    				catch(Exception e)
120
    				{
121
    					logMetacat.warn("Couldn't sleep 5 seconds");
122
    				}
123
    			}
124
    			catch(Exception e)
125
    			{
126
    				logMetacat.warn("The docid "+docid+" with owner "+owner+" couldn't be transformed to eml-2.1.0 since "+e.getMessage());
127
    				transformErrorLog("The docid "+docid+" with owner "+owner+" couldn't be transformed to eml-2.1.0 since "+e.getMessage());
128
    			}
129
    		}
130
    	}
131
    }
132
    
133
    /*
134
     * Handle single eml201 or eml 200 document: read the document, transform it to eml210 document 
135
     * then save it to 210 document into metacat
136
     */
137
    private  void handleSingleEML200Document(String docidWithRev, String owner) throws Exception
138
    {
139
    	DocumentImpl docImpl = new DocumentImpl(docidWithRev);
140
    	String eml200Content = docImpl.toString();
141
    	StringReader eml200Source= new StringReader(eml200Content);
142
    	//PipedWriter eml210OutputAfterTransform = new PipedWriter();
143
    	//PipedReader eml210SourceForNewDoc = new PipedReader();
144
    	//eml210SourceForNewDoc.connect(eml210OutputAfterTransform);
145
    	StringWriter strWriter = new StringWriter();
146
    	String newId = increaseRevisionNumber(docidWithRev);
147
    	if(newId != null)
148
    	{
149
    	     transformEML200ToEML210(eml200Source, eml210StyleFile,  strWriter, newId);
150
    	     String eml210Content = strWriter.toString();
151
    	     String rule = DocumentImpl.EML210;
152
             // using emlparser to check id validation
153
             EMLParser parser = new EMLParser(eml210Content);
154
             DocumentImplWrapper documentWrapper = new DocumentImplWrapper(rule, true, true);
155
//             StringReader xml = new StringReader(eml210Content);
156
             String  doAction = "UPDATE";
157
             String pub = null;
158
             String []groups = null;
159
             DBConnection dbconn = null;
160
             StringReader dtd = null;
161
             int serialNumber = -1;
162
             String formatId = null;
163
             try
164
             {
165
            	 dbconn = DBConnectionPool
166
                 .getDBConnection("EMLVersionsTransformer.handleSingleEML200Document");
167
                  serialNumber = dbconn.getCheckOutSerialNumber();
168
                  documentWrapper.write(dbconn, eml210Content, pub, dtd,
169
                          doAction, newId, owner, groups, null, formatId);
170
                  logMetacat.warn("Doc "+docidWithRev+" was transformed to eml210 with new id "+newId);
171
                  transformLog("Doc "+docidWithRev+" was transformed to eml210 with new id "+newId);
172
             }
173
             catch(Exception e)
174
             {
175
            	 throw e;
176
             }
177
             finally
178
             {
179
            	 // Return db connection
180
                 DBConnectionPool.returnDBConnection(dbconn, serialNumber);
181
             }
182
    	}
183
    	else
184
    	{
185
    		logMetacat.warn("Couldn't increase docid "+docidWithRev+"'s revision");
186
    	}
187
    }
188

    
189
    /*
190
     * Transform single eml201 (Reader) to eml 210 (Writer)
191
     */
192
    private static void transformEML200ToEML210(Reader reader, String xslfile, Writer writer, String packageid) throws Exception{    
193
        	Hashtable param = null;
194
            if (packageid != null)
195
            {
196
            	param = new Hashtable();
197
            	param.put("package-id", packageid);
198
            }
199
            EMLVersionsTransformer.transform(reader, xslfile, writer, param);
200
         
201
    }
202

    
203

    
204
    /*
205
     * Transform an XML document using an XSLT stylesheet to another format,
206
     * probably HTML or another XML document format.
207
     *
208
     * @param doc the document to be transformed
209
     * @param xslSystemId the system location of the stylesheet
210
     * @param pw the PrintWriter to which output is printed
211
     * @param params some parameters for inclusion to the transformation
212
     */
213
    private static void transform(Reader doc, String xslSystemId,
214
        Writer pw, Hashtable param) throws Exception
215
    {
216
        
217
            StreamSource xslSource = 
218
                new StreamSource(xslSystemId);
219
            xslSource.setSystemId(xslSystemId);
220
            // Create a stylesheet from the system id that was found
221
            TransformerFactory tFactory = TransformerFactory.newInstance();
222
            Transformer transformer = tFactory.newTransformer(xslSource);
223

    
224
            // Set up parameters for transformation
225
            if ( param != null) {
226
                Enumeration en = param.keys();
227
                while (en.hasMoreElements()) {
228
                    String key =(String)en.nextElement();
229
                    String value = ((String)(param.get(key)));
230
                    transformer.setParameter(key, value);
231
                }
232
            }
233

    
234
            // Run the transform engine
235
            StreamSource ss = new StreamSource(doc);
236
            StreamResult sr = new StreamResult(pw);
237
            transformer.transform(ss, sr);
238
        
239
    }
240
    
241
    /*
242
     * Get list of document (docid and owner) which type is eml200 or eml201. 
243
     * The docid in the list will have revision number too.
244
     */
245
    private Vector getEML2DocList()
246
    {
247
    	Vector list = new Vector();
248
    	 DBConnection dbconn = null;
249
         int serialNumber = -1;
250
         String sql = "select docid, rev, user_owner from xml_documents where doctype like 'eml://ecoinformatics.org/eml-2.0.1' or doctype like 'eml://ecoinformatics.org/eml-2.0.0'";
251
         PreparedStatement pstmt = null;
252
         try {
253
             dbconn = DBConnectionPool
254
                     .getDBConnection("EMLVersionsTransformer.getEML2DocList");
255
             serialNumber = dbconn.getCheckOutSerialNumber();
256
             pstmt = dbconn.prepareStatement(sql.toString());
257
             pstmt.execute();
258
             ResultSet rs = pstmt.getResultSet();
259
             boolean tableHasRows = rs.next();
260
             while (tableHasRows) {
261
                 String docidWithoutRev = rs.getString(1);
262
                 int rev = rs.getInt(2);
263
                 String owner = rs.getString(3);
264
                 String docidWithRev = docidWithoutRev+DOT+rev;
265
                 logMetacat.info("The docid "+docidWithRev+" with owner "+owner+" will be added into list which will be transformed to eml-2.1.0");
266
                 OwnerAndDocid pair = new OwnerAndDocid(owner, docidWithRev);;
267
                 list.add(pair);
268
                 tableHasRows = rs.next();
269
             }
270
             pstmt.close();
271

    
272
        
273
        } catch (SQLException e) {
274
             logMetacat.error("error in DocumentImpl.getDocumentInfo: "
275
                + e.getMessage());
276
             e.printStackTrace(System.out);
277
        } finally {
278
            try {
279
                 pstmt.close();
280
            } catch (SQLException ee) {
281
              logMetacat.error(
282
                    "error in DocumentImple.getDocumentInfo: "
283
                            + ee.getMessage());
284
           } finally {
285
              DBConnectionPool.returnDBConnection(dbconn, serialNumber);
286
        }
287
      }
288
      return list;
289
    }
290
    
291
    /*
292
     * Increase revision number for the given docid. tao.1.1 will be tao.1.2. null will be returned
293
     * if couldn't increase it.
294
     */
295
    private static String increaseRevisionNumber(String docidWithRev)
296
    {
297
    	String newid = null;
298
    	try
299
    	{
300
    	  if (docidWithRev != null)
301
    	  {
302
    		int index = docidWithRev.lastIndexOf(DOT);
303
    		if (index != -1)
304
    		{
305
    			String firstTwoParts = docidWithRev.substring(0,index);
306
    			String revStr = docidWithRev.substring(index+1);
307
    			Integer revObj = new Integer(revStr);
308
    			int rev = revObj.intValue();
309
    			rev= rev+1;
310
    			newid = firstTwoParts+DOT+rev;
311
    		}
312
    	  }
313
    	}
314
    	catch(Exception e)
315
    	{
316
    		logMetacat.warn("Couldn't increase revision number since "+e.getMessage());
317
    	}
318
    	return newid;
319
    }
320
    
321
    
322
    /*
323
	 * Method for writing transformation messages to a log file specified in
324
	 * metacat.properties
325
	 */
326
	private static void transformLog(String message) {
327
		try {
328
			FileOutputStream fos = 
329
				new FileOutputStream(PropertyService.getProperty("replication.logdir")
330
					+ "/transform.log", true);
331
			PrintWriter pw = new PrintWriter(fos);
332
			SimpleDateFormat formatter = new SimpleDateFormat("yy-MM-dd HH:mm:ss");
333
			java.util.Date localtime = new java.util.Date();
334
			String dateString = formatter.format(localtime);
335
			dateString += " :: " + message;
336
			// time stamp each entry
337
			pw.println(dateString);
338
			pw.flush();
339
		} catch (Exception e) {
340
			logMetacat.warn("error writing to transform log from "
341
					+ "EMLVersionTransformer.transformlLog: " + e.getMessage());
342
			// e.printStackTrace(System.out);
343
		}
344
	}
345

    
346
  /*
347
	 * Method for writing transform messages to a log file specified in
348
	 * metacat.properties
349
	 */
350
  private static void transformErrorLog(String message)
351
  {
352
    try
353
    {
354
    	FileOutputStream fos = 
355
			new FileOutputStream(PropertyService.getProperty("replication.logdir")
356
				+ "/transformerror.log", true);
357
      PrintWriter pw = new PrintWriter(fos);
358
      SimpleDateFormat formatter = new SimpleDateFormat ("yy-MM-dd HH:mm:ss");
359
      java.util.Date localtime = new java.util.Date();
360
      String dateString = formatter.format(localtime);
361
      dateString += " :: " + message;
362
      //time stamp each entry
363
      pw.println(dateString);
364
      pw.flush();
365
    }
366
    catch(Exception e)
367
    {
368
      logMetacat.warn("error writing to transforming error log from " +
369
                         "EMLVersionTransformer.transformErrorLog: " + e.getMessage());
370
      //e.printStackTrace(System.out);
371
    }
372
  }
373
    
374
    /*
375
     * Class reprents a document's docid and its owner 
376
     * @author tao
377
     *
378
     */
379
    class OwnerAndDocid{
380
    	private String owner = null;
381
    	private String docidWithRev = null;
382
    	
383
    	public OwnerAndDocid(String owner, String docidWithRev)
384
    	{
385
    		this.owner = owner;
386
    		this.docidWithRev = docidWithRev;
387
    	}
388
    	
389
    	public String getOwner()
390
    	{
391
    		return owner;
392
    	}
393
    	
394
    	public String getDocid()
395
    	{
396
    		return docidWithRev;
397
    	}
398
    }
399
    
400

    
401
  
402
}
403

    
(7-7/18)