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

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

Changed the "a_doc" variable to be a StringBuffer instead of a String, to speed things up considerably in some cases.

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