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 = strWriter.toString();
|
134
|
String rule = DocumentImpl.EML210;
|
135
|
// using emlparser to check id validation
|
136
|
EMLParser parser = new EMLParser(eml210Content);
|
137
|
DocumentImplWrapper documentWrapper = new DocumentImplWrapper(rule, true);
|
138
|
StringReader xml = new StringReader(eml210Content);
|
139
|
String doAction = "UPDATE";
|
140
|
String pub = null;
|
141
|
String []groups = null;
|
142
|
DBConnection dbconn = null;
|
143
|
StringReader dtd = null;
|
144
|
int serialNumber = -1;
|
145
|
try
|
146
|
{
|
147
|
dbconn = DBConnectionPool
|
148
|
.getDBConnection("EMLVersionsTransformer.handleSingleEML200Document");
|
149
|
serialNumber = dbconn.getCheckOutSerialNumber();
|
150
|
documentWrapper.write(dbconn, xml, pub, dtd,
|
151
|
doAction, newId, owner, groups);
|
152
|
logMetacat.warn("Doc "+docidWithRev+"was transformed to eml210 with new id "+newId);
|
153
|
}
|
154
|
catch(Exception e)
|
155
|
{
|
156
|
throw e;
|
157
|
}
|
158
|
finally
|
159
|
{
|
160
|
// Return db connection
|
161
|
DBConnectionPool.returnDBConnection(dbconn, serialNumber);
|
162
|
}
|
163
|
}
|
164
|
else
|
165
|
{
|
166
|
logMetacat.warn("Couldn't increase docid "+docidWithRev+"'s revision");
|
167
|
}
|
168
|
}
|
169
|
|
170
|
/*
|
171
|
* Transform single eml201 (Reader) to eml 210 (Writer)
|
172
|
*/
|
173
|
private static void transformEML200ToEML210(Reader reader, String xslfile, Writer writer, String packageid) throws Exception{
|
174
|
Hashtable param = null;
|
175
|
if (packageid != null)
|
176
|
{
|
177
|
param = new Hashtable();
|
178
|
param.put("package-id", packageid);
|
179
|
}
|
180
|
EMLVersionsTransformer.transform(reader, xslfile, writer, param);
|
181
|
|
182
|
}
|
183
|
|
184
|
|
185
|
/*
|
186
|
* Transform an XML document using an XSLT stylesheet to another format,
|
187
|
* probably HTML or another XML document format.
|
188
|
*
|
189
|
* @param doc the document to be transformed
|
190
|
* @param xslSystemId the system location of the stylesheet
|
191
|
* @param pw the PrintWriter to which output is printed
|
192
|
* @param params some parameters for inclusion to the transformation
|
193
|
*/
|
194
|
private static void transform(Reader doc, String xslSystemId,
|
195
|
Writer pw, Hashtable param) throws Exception
|
196
|
{
|
197
|
|
198
|
StreamSource xslSource =
|
199
|
new StreamSource(xslSystemId);
|
200
|
xslSource.setSystemId(xslSystemId);
|
201
|
// Create a stylesheet from the system id that was found
|
202
|
TransformerFactory tFactory = TransformerFactory.newInstance();
|
203
|
Transformer transformer = tFactory.newTransformer(xslSource);
|
204
|
|
205
|
// Set up parameters for transformation
|
206
|
if ( param != null) {
|
207
|
Enumeration en = param.keys();
|
208
|
while (en.hasMoreElements()) {
|
209
|
String key =(String)en.nextElement();
|
210
|
String value = ((String)(param.get(key)));
|
211
|
transformer.setParameter(key, value);
|
212
|
}
|
213
|
}
|
214
|
|
215
|
// Run the transform engine
|
216
|
StreamSource ss = new StreamSource(doc);
|
217
|
StreamResult sr = new StreamResult(pw);
|
218
|
transformer.transform(ss, sr);
|
219
|
|
220
|
}
|
221
|
|
222
|
/*
|
223
|
* Get list of document (docid and owner) which type is eml200 or eml201.
|
224
|
* The docid in the list will have revision number too.
|
225
|
*/
|
226
|
private Vector getEML2DocList()
|
227
|
{
|
228
|
Vector list = new Vector();
|
229
|
DBConnection dbconn = null;
|
230
|
int serialNumber = -1;
|
231
|
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'";
|
232
|
PreparedStatement pstmt = null;
|
233
|
try {
|
234
|
dbconn = DBConnectionPool
|
235
|
.getDBConnection("EMLVersionsTransformer.getEML2DocList");
|
236
|
serialNumber = dbconn.getCheckOutSerialNumber();
|
237
|
pstmt = dbconn.prepareStatement(sql.toString());
|
238
|
pstmt.execute();
|
239
|
ResultSet rs = pstmt.getResultSet();
|
240
|
boolean tableHasRows = rs.next();
|
241
|
while (tableHasRows) {
|
242
|
String docidWithoutRev = rs.getString(1);
|
243
|
int rev = rs.getInt(2);
|
244
|
String owner = rs.getString(3);
|
245
|
String docidWithRev = docidWithoutRev+DOT+rev;
|
246
|
logMetacat.info("The docid "+docidWithRev+" with owner "+owner+" will be added into list which will be transformed to eml-2.1.0");
|
247
|
OwnerAndDocid pair = new OwnerAndDocid(owner, docidWithRev);;
|
248
|
list.add(pair);
|
249
|
tableHasRows = rs.next();
|
250
|
}
|
251
|
pstmt.close();
|
252
|
|
253
|
|
254
|
} catch (SQLException e) {
|
255
|
logMetacat.error("error in DocumentImpl.getDocumentInfo: "
|
256
|
+ e.getMessage());
|
257
|
e.printStackTrace(System.out);
|
258
|
} finally {
|
259
|
try {
|
260
|
pstmt.close();
|
261
|
} catch (SQLException ee) {
|
262
|
logMetacat.error(
|
263
|
"error in DocumentImple.getDocumentInfo: "
|
264
|
+ ee.getMessage());
|
265
|
} finally {
|
266
|
DBConnectionPool.returnDBConnection(dbconn, serialNumber);
|
267
|
}
|
268
|
}
|
269
|
return list;
|
270
|
}
|
271
|
|
272
|
/*
|
273
|
* Increase revision number for the given docid. tao.1.1 will be tao.1.2. null will be returned
|
274
|
* if couldn't increase it.
|
275
|
*/
|
276
|
private static String increaseRevisionNumber(String docidWithRev)
|
277
|
{
|
278
|
String newid = null;
|
279
|
try
|
280
|
{
|
281
|
if (docidWithRev != null)
|
282
|
{
|
283
|
int index = docidWithRev.lastIndexOf(DOT);
|
284
|
if (index != -1)
|
285
|
{
|
286
|
String firstTwoParts = docidWithRev.substring(0,index);
|
287
|
String revStr = docidWithRev.substring(index+1);
|
288
|
Integer revObj = new Integer(revStr);
|
289
|
int rev = revObj.intValue();
|
290
|
rev= rev+1;
|
291
|
newid = firstTwoParts+DOT+rev;
|
292
|
}
|
293
|
}
|
294
|
}
|
295
|
catch(Exception e)
|
296
|
{
|
297
|
logMetacat.warn("Couldn't increase revision number since "+e.getMessage());
|
298
|
}
|
299
|
return newid;
|
300
|
}
|
301
|
|
302
|
/*
|
303
|
* Class reprents a document's docid and its owner
|
304
|
* @author tao
|
305
|
*
|
306
|
*/
|
307
|
class OwnerAndDocid{
|
308
|
private String owner = null;
|
309
|
private String docidWithRev = null;
|
310
|
|
311
|
public OwnerAndDocid(String owner, String docidWithRev)
|
312
|
{
|
313
|
this.owner = owner;
|
314
|
this.docidWithRev = docidWithRev;
|
315
|
}
|
316
|
|
317
|
public String getOwner()
|
318
|
{
|
319
|
return owner;
|
320
|
}
|
321
|
|
322
|
public String getDocid()
|
323
|
{
|
324
|
return docidWithRev;
|
325
|
}
|
326
|
}
|
327
|
|
328
|
|
329
|
|
330
|
}
|
331
|
|