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.util.Enumeration;
32
import java.util.Hashtable;
33
import java.util.Vector;
34

    
35
import org.apache.log4j.Logger;
36

    
37
import edu.ucsb.nceas.metacat.DBConnection;
38
import edu.ucsb.nceas.metacat.DBConnectionPool;
39
import edu.ucsb.nceas.metacat.DocumentImpl;
40
import edu.ucsb.nceas.metacat.DocumentImplWrapper;
41
import edu.ucsb.nceas.metacat.McdbException;
42
import edu.ucsb.nceas.metacat.service.PropertyService;
43

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

    
53

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

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

    
171
    /*
172
     * Transform single eml201 (Reader) to eml 210 (Writer)
173
     */
174
    private static void transformEML200ToEML210(Reader reader, String xslfile, Writer writer, String packageid) throws Exception{    
175
        	Hashtable param = null;
176
            if (packageid != null)
177
            {
178
            	param = new Hashtable();
179
            	param.put("package-id", packageid);
180
            }
181
            EMLVersionsTransformer.transform(reader, xslfile, writer, param);
182
         
183
    }
184

    
185

    
186
    /*
187
     * Transform an XML document using an XSLT stylesheet to another format,
188
     * probably HTML or another XML document format.
189
     *
190
     * @param doc the document to be transformed
191
     * @param xslSystemId the system location of the stylesheet
192
     * @param pw the PrintWriter to which output is printed
193
     * @param params some parameters for inclusion to the transformation
194
     */
195
    private static void transform(Reader doc, String xslSystemId,
196
        Writer pw, Hashtable param) throws Exception
197
    {
198
        
199
            StreamSource xslSource = 
200
                new StreamSource(xslSystemId);
201
            xslSource.setSystemId(xslSystemId);
202
            // Create a stylesheet from the system id that was found
203
            TransformerFactory tFactory = TransformerFactory.newInstance();
204
            Transformer transformer = tFactory.newTransformer(xslSource);
205

    
206
            // Set up parameters for transformation
207
            if ( param != null) {
208
                Enumeration en = param.keys();
209
                while (en.hasMoreElements()) {
210
                    String key =(String)en.nextElement();
211
                    String value = ((String)(param.get(key)));
212
                    transformer.setParameter(key, value);
213
                }
214
            }
215

    
216
            // Run the transform engine
217
            StreamSource ss = new StreamSource(doc);
218
            StreamResult sr = new StreamResult(pw);
219
            transformer.transform(ss, sr);
220
        
221
    }
222
    
223
    /*
224
     * Get list of document (docid and owner) which type is eml200 or eml201. 
225
     * The docid in the list will have revision number too.
226
     */
227
    private Vector getEML2DocList()
228
    {
229
    	Vector list = new Vector();
230
    	 DBConnection dbconn = null;
231
         int serialNumber = -1;
232
         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'";
233
         PreparedStatement pstmt = null;
234
         try {
235
             dbconn = DBConnectionPool
236
                     .getDBConnection("EMLVersionsTransformer.getEML2DocList");
237
             serialNumber = dbconn.getCheckOutSerialNumber();
238
             pstmt = dbconn.prepareStatement(sql.toString());
239
             pstmt.execute();
240
             ResultSet rs = pstmt.getResultSet();
241
             boolean tableHasRows = rs.next();
242
             if (tableHasRows) {
243
                 String docidWithoutRev = rs.getString(1);
244
                 int rev = rs.getInt(2);
245
                 String owner = rs.getString(3);
246
                 String docidWithRev = docidWithoutRev+DOT+rev;
247
                 logMetacat.info("The docid "+docidWithRev+" with owner "+owner+" will be added into list which will be transformed to eml-2.1.0");
248
                 OwnerAndDocid pair = new OwnerAndDocid(owner, docidWithRev);;
249
                 list.add(pair);
250
                 tableHasRows = rs.next();
251
             }
252
             pstmt.close();
253

    
254
        
255
        } catch (SQLException e) {
256
             logMetacat.error("error in DocumentImpl.getDocumentInfo: "
257
                + e.getMessage());
258
             e.printStackTrace(System.out);
259
        } finally {
260
            try {
261
                 pstmt.close();
262
            } catch (SQLException ee) {
263
              logMetacat.error(
264
                    "error in DocumentImple.getDocumentInfo: "
265
                            + ee.getMessage());
266
           } finally {
267
              DBConnectionPool.returnDBConnection(dbconn, serialNumber);
268
        }
269
      }
270
      return list;
271
    }
272
    
273
    /*
274
     * Increase revision number for the given docid. tao.1.1 will be tao.1.2. null will be returned
275
     * if couldn't increase it.
276
     */
277
    private static String increaseRevisionNumber(String docidWithRev)
278
    {
279
    	String newid = null;
280
    	try
281
    	{
282
    	  if (docidWithRev != null)
283
    	  {
284
    		int index = docidWithRev.lastIndexOf(DOT);
285
    		if (index != -1)
286
    		{
287
    			String firstTwoParts = docidWithRev.substring(0,index);
288
    			String revStr = docidWithRev.substring(index+1);
289
    			Integer revObj = new Integer(revStr);
290
    			int rev = revObj.intValue();
291
    			rev= rev+1;
292
    			newid = firstTwoParts+DOT+rev;
293
    		}
294
    	  }
295
    	}
296
    	catch(Exception e)
297
    	{
298
    		logMetacat.warn("Couldn't increase revision number since "+e.getMessage());
299
    	}
300
    	return newid;
301
    }
302
    
303
    /*
304
     * Class reprents a document's docid and its owner 
305
     * @author tao
306
     *
307
     */
308
    class OwnerAndDocid{
309
    	private String owner = null;
310
    	private String docidWithRev = null;
311
    	
312
    	public OwnerAndDocid(String owner, String docidWithRev)
313
    	{
314
    		this.owner = owner;
315
    		this.docidWithRev = docidWithRev;
316
    	}
317
    	
318
    	public String getOwner()
319
    	{
320
    		return owner;
321
    	}
322
    	
323
    	public String getDocid()
324
    	{
325
    		return docidWithRev;
326
    	}
327
    }
328
    
329

    
330
  
331
}
332

    
(3-3/12)