source: main/trunk/greenstone2/build-src/src/java/org/nzdl/gsdl/ApplyXSLT.java@ 22736

Last change on this file since 22736 was 22736, checked in by mdewsnip, 14 years ago

Added copyright header to build-src/src/java/org/nzdl/gsdl/ApplyXSLT.java and build-src/src/java/org/nzdl/gsdl/ApplyXSLTUtil.java.

  • Property svn:keywords set to Author Date Id Revision
File size: 11.8 KB
Line 
1/**********************************************************************
2 *
3 * ApplyXSLT.java
4 *
5 * Copyright 2006-2010 The New Zealand Digital Library Project
6 *
7 * A component of the Greenstone digital library software
8 * from the New Zealand Digital Library Project at the
9 * University of Waikato, New Zealand.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 *********************************************************************/
26
27
28package org.nzdl.gsdl;
29
30import java.io.*;
31
32import javax.xml.transform.Transformer;
33import javax.xml.transform.TransformerConfigurationException;
34import javax.xml.transform.TransformerException;
35import javax.xml.transform.TransformerFactory;
36import javax.xml.transform.stream.StreamResult;
37import javax.xml.transform.stream.StreamSource;
38
39import javax.xml.parsers.*;
40import javax.xml.transform.dom.*;
41import org.w3c.dom.*;
42
43
44
45/**
46 * Use the TraX interface to perform a transformation in the simplest manner possible
47 * (3 statements).
48 */
49public class ApplyXSLT
50{
51
52 public static final String DOC_START = new String ("<?DocStart?>");
53 public static final String DOC_END = new String ("<?DocEnd?>");
54 public static final String INPUT_END = new String ("<?Done?>");
55
56 private static final String RECORD_ELEMENT = "record";
57 private static final String CONTROLFIELD_ELEMENT = "controlfield";
58 private static final String SUBFIELD_ELEMENT = "subfield";
59 private static final String LEADER_ELEMENT = "leader";
60
61 private final int BEFORE_READING = 0;
62 private final int IS_READING = 1;
63 private String xsl_file;
64 private String mapping_file;
65
66 public ApplyXSLT(){}
67
68 public ApplyXSLT(String xsl_file)
69 {
70 this.xsl_file = xsl_file;
71 }
72
73 public ApplyXSLT(String xsl_file,String mapping_file){
74 this.xsl_file = xsl_file;
75 this.mapping_file = mapping_file;
76 }
77
78 private boolean process()
79 {
80 try{
81
82 // Use System InputStream to receive piped data from the perl program
83 InputStreamReader ir = new InputStreamReader(System.in, "UTF8");
84 BufferedReader br = new BufferedReader(ir);
85
86 int system_status = BEFORE_READING;
87 StringBuffer a_doc = new StringBuffer();
88 String output_file = new String();
89
90
91 while (br.ready()) {
92
93 String this_line = br.readLine();
94 if(system_status == BEFORE_READING){
95 if(this_line.compareTo(DOC_START) == 0){
96 output_file = br.readLine(); // read the next line as the output file name
97 system_status = IS_READING;
98 a_doc = new StringBuffer();
99 }
100 else if(this_line.compareTo(INPUT_END) == 0){
101 return true;
102 }
103 else{
104 System.err.println("Undefined process status:" + this_line);
105 system_status = BEFORE_READING;
106 }
107
108 }
109 else if(system_status == IS_READING){
110 if(this_line.compareTo(DOC_END) == 0){
111 boolean result = false;
112 if (mapping_file !=null && !mapping_file.equals("")){
113 result = translateXMLWithMapping(a_doc.toString(), output_file);
114 }
115 else{
116 result = translateXML(a_doc.toString(), output_file);
117 }
118
119 if (!result){
120 System.err.println("Translation Failed!!");
121 return false;
122 }
123
124 system_status = BEFORE_READING;
125
126 }
127 else{
128 a_doc.append(this_line + "\n");
129 }
130 }
131 else{
132 System.err.println ("Undefined system status in ApplyXSLT.java main().");
133 System.exit(-1);
134 }
135
136 }
137 }catch (Exception e)
138 {
139 System.err.println("Receiving piped data error!" + e.toString());
140 }
141
142 return false;
143 }
144
145
146 private boolean translateXML(String full_doc, String output_file)
147 throws IOException,TransformerException, TransformerConfigurationException, FileNotFoundException
148 {
149
150 StringReader str = new StringReader(full_doc) ;
151
152 TransformerFactory tFactory = TransformerFactory.newInstance();
153 Transformer transformer = tFactory.newTransformer(new StreamSource(xsl_file));
154 transformer.transform(new StreamSource(str), new StreamResult(new FileOutputStream(output_file)));
155 return true;
156 }
157
158 private boolean translateXMLWithMapping(String full_doc, String output_file)
159 throws IOException,TransformerException, TransformerConfigurationException, FileNotFoundException
160 {
161 StringReader str = new StringReader(full_doc) ;
162
163 try{
164 TransformerFactory tFactory = TransformerFactory.newInstance();
165 Transformer transformer = tFactory.newTransformer(new StreamSource(xsl_file));
166
167 Document mapping_doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(mapping_file);
168 Element mapping =mapping_doc.getDocumentElement();
169
170 transformer.setParameter("mapping",mapping);
171
172 Document output_doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
173
174 transformer.transform(new StreamSource(str), new DOMResult(output_doc));
175
176 calculateRecordsLength(output_doc);
177
178 transformer = tFactory.newTransformer();
179
180 transformer.transform(new DOMSource(output_doc), new StreamResult(new FileOutputStream(output_file)));
181
182 }
183 catch(Exception e){
184 e.printStackTrace();
185 return false;
186 }
187
188 return true;
189 }
190
191 private void calculateRecordsLength(Document output_doc){
192 NodeList records = output_doc.getDocumentElement().getElementsByTagName(RECORD_ELEMENT);
193
194 for(int i=0;i<records.getLength();i++){
195 Element record = (Element)records.item(i);
196 calculateRecordLength(record);
197 }
198 }
199
200 private void calculateRecordLength(Element record){
201 int total_length =0;
202 NodeList controlfileds = record.getElementsByTagName(CONTROLFIELD_ELEMENT);
203 for(int i=0;i<controlfileds.getLength();i++){
204 Element controlfiled = (Element)controlfileds.item(i);
205 total_length +=getElementTextValue(controlfiled).length();
206 }
207
208 NodeList subfileds = record.getElementsByTagName(SUBFIELD_ELEMENT);
209 for(int i=0;i<subfileds.getLength();i++){
210 Element subfiled = (Element)subfileds.item(i);
211 total_length +=getElementTextValue(subfiled).length();
212 }
213
214 String record_length = total_length+"";
215 //fill in a extra digit as record length needs to be five characters long
216 if (total_length < 10000){
217 record_length = "0"+record_length;
218 if (total_length < 1000){
219 record_length = "0"+record_length;
220 }
221 if (total_length < 100){
222 record_length = "0"+record_length;
223 }
224 if (total_length < 10){
225 record_length = "0"+record_length;
226 }
227
228 }
229
230 NodeList leaders = record.getElementsByTagName(LEADER_ELEMENT);
231
232 //only one leader element
233 if (leaders.getLength() >0){
234 Element leader_element = (Element)leaders.item(0);
235 removeFirstTextNode(leader_element);
236 leader_element.insertBefore(leader_element.getOwnerDocument().createTextNode(record_length),leader_element.getFirstChild());
237 }
238
239 }
240
241 private void removeFirstTextNode(Element element){
242 //remove the first text node
243 NodeList children_nodelist = element.getChildNodes();
244 for (int i = 0; i < children_nodelist.getLength(); i++) {
245 Node child_node = children_nodelist.item(i);
246 if (child_node.getNodeType() == Node.TEXT_NODE) {
247 element.removeChild(child_node);
248 return;
249 }
250 }
251
252 }
253
254 private String getElementTextValue(Element element)
255 {
256 String text ="";
257
258 // Find the node child
259 NodeList children_nodelist = element.getChildNodes();
260 for (int i = 0; i < children_nodelist.getLength(); i++) {
261 Node child_node = children_nodelist.item(i);
262 if (child_node.getNodeType() == Node.TEXT_NODE) {
263 text +=child_node.getNodeValue();
264 }
265 }
266
267 return text;
268 }
269
270
271 private void setMappingVariable(Document style_doc){
272 Node child = style_doc.getDocumentElement().getFirstChild();
273 while(child != null) {
274 String name = child.getNodeName();
275 if (name.equals("xsl:variable")) {
276 Element variable_element = (Element)child;
277 if ( variable_element.getAttribute("name").trim().equals("mapping")){
278 variable_element.setAttribute("select","document('"+mapping_file+"')/Mapping");
279 }
280 }
281 child = child.getNextSibling();
282 }
283
284 }
285
286
287 private void translate(String xml_file, String xsl_file, String output_file)throws IOException,TransformerException, TransformerConfigurationException, FileNotFoundException, IOException{
288
289 TransformerFactory tFactory = TransformerFactory.newInstance();
290 Transformer transformer = tFactory.newTransformer(new StreamSource(xsl_file));
291
292 OutputStreamWriter output = null;
293 if (output_file.equals("")) {
294 output = new OutputStreamWriter(System.out, "UTF-8");
295 }
296 else{
297 output = new OutputStreamWriter(new FileOutputStream(output_file), "UTF-8");
298 }
299
300 transformer.transform(new StreamSource(new File(xml_file)),new StreamResult(output));
301
302 }
303
304 static public String replaceAll(String source_string, String match_regexp, String replace_string)
305 {
306 return source_string.replaceAll(match_regexp, replace_string);
307 }
308
309
310 public static void main(String[] args)
311 {
312
313 String xml_file="";
314 String xsl_file="";
315 String mapping_file="";
316 String output_file="";
317
318 // Checking Arguments
319 if(args.length < 1)
320 {
321 printUsage();
322 }
323
324 for (int i=0;i<args.length;i++){
325 if (args[i].equals("-m") && i+1 < args.length && !args[i+1].startsWith("-")){
326 mapping_file = args[++i];
327 checkFile(mapping_file.replaceAll("file:///",""));
328 }
329 else if (args[i].equals("-x") && i+1 < args.length && !args[i+1].startsWith("-")){
330 xml_file = args[++i];
331 checkFile(xml_file.replaceAll("file:///",""));
332 }
333 else if(args[i].equals("-t") && i+1 < args.length && !args[i+1].startsWith("-")){
334 xsl_file = args[++i];
335 checkFile( xsl_file.replaceAll("file:///",""));
336 }
337 else if(args[i].equals("-o") && i+1 < args.length && !args[i+1].startsWith("-")){
338 output_file = args[++i];
339
340 }
341 else if(args[i].equals("-h")){
342 printUsage();
343 }
344 else{
345 printUsage();
346 }
347
348 }
349
350
351 ApplyXSLT core = null;
352
353 if (xml_file.equals("") && !xsl_file.equals("")){//read from pipe line
354 if (mapping_file.equals("")){
355 core = new ApplyXSLT(xsl_file);
356 }
357 else{
358 core = new ApplyXSLT(xsl_file,mapping_file);
359 }
360
361 if (core != null){
362 core.process();
363 }
364 else{
365 printUsage();
366 }
367 }
368 else if(!xml_file.equals("") && !xsl_file.equals("")){
369 core = new ApplyXSLT();
370 try {
371 core.translate(xml_file,xsl_file,output_file);
372 }
373 catch(Exception e){e.printStackTrace();}
374 }
375 else{
376 printUsage();
377 }
378
379 }
380
381 private static void checkFile(String filename){
382 File file = new File(filename);
383 if (!file.exists()){
384 System.out.println("Error: "+filename+" doesn't exist!");
385 System.exit(-1);
386 }
387 }
388
389 private static void printUsage(){
390 System.out.println("Usage:ApplyXSLT -x File -t File [-m File] [-o File]");
391 System.out.println("\t-x specifies the xml file (Note: optional for piped xml data)");
392 System.out.println("\t-t specifies the xsl file");
393 System.out.println("\t-m specifies the mapping file (for MARCXMLPlugout.pm only)");
394 System.out.println("\t-o specifies the output file name (output to screen if this option is absent)");
395 System.exit(-1);
396 }
397}
398
399
Note: See TracBrowser for help on using the repository browser.