OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [tools/] [external/] [asm/] [org/] [objectweb/] [asm/] [xml/] [Processor.java] - Blame information for rev 779

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 779 jeremybenn
/***
2
 * ASM XML Adapter
3
 * Copyright (c) 2004, Eugene Kuleshov
4
 * All rights reserved.
5
 *
6
 * Redistribution and use in source and binary forms, with or without
7
 * modification, are permitted provided that the following conditions
8
 * are met:
9
 * 1. Redistributions of source code must retain the above copyright
10
 *    notice, this list of conditions and the following disclaimer.
11
 * 2. Redistributions in binary form must reproduce the above copyright
12
 *    notice, this list of conditions and the following disclaimer in the
13
 *    documentation and/or other materials provided with the distribution.
14
 * 3. Neither the name of the copyright holders nor the names of its
15
 *    contributors may be used to endorse or promote products derived from
16
 *    this software without specific prior written permission.
17
 *
18
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
28
 * THE POSSIBILITY OF SUCH DAMAGE.
29
 */
30
package org.objectweb.asm.xml;
31
 
32
import java.io.BufferedOutputStream;
33
import java.io.ByteArrayInputStream;
34
import java.io.ByteArrayOutputStream;
35
import java.io.FileInputStream;
36
import java.io.FileOutputStream;
37
import java.io.IOException;
38
import java.io.InputStream;
39
import java.io.OutputStream;
40
import java.io.OutputStreamWriter;
41
import java.io.Writer;
42
import java.util.zip.ZipEntry;
43
import java.util.zip.ZipInputStream;
44
import java.util.zip.ZipOutputStream;
45
 
46
import javax.xml.transform.Source;
47
import javax.xml.transform.Templates;
48
import javax.xml.transform.TransformerConfigurationException;
49
import javax.xml.transform.TransformerException;
50
import javax.xml.transform.TransformerFactory;
51
import javax.xml.transform.sax.SAXResult;
52
import javax.xml.transform.sax.SAXSource;
53
import javax.xml.transform.sax.SAXTransformerFactory;
54
import javax.xml.transform.sax.TransformerHandler;
55
import javax.xml.transform.stream.StreamSource;
56
 
57
import org.objectweb.asm.ClassReader;
58
 
59
import org.xml.sax.Attributes;
60
import org.xml.sax.ContentHandler;
61
import org.xml.sax.InputSource;
62
import org.xml.sax.SAXException;
63
import org.xml.sax.XMLReader;
64
import org.xml.sax.ext.LexicalHandler;
65
import org.xml.sax.helpers.AttributesImpl;
66
import org.xml.sax.helpers.DefaultHandler;
67
import org.xml.sax.helpers.XMLReaderFactory;
68
 
69
/**
70
 * Processor is a command line tool that can be used for bytecode waving
71
 * directed by XSL transformation. <p> In order to use a concrete XSLT engine,
72
 * system property <tt>javax.xml.transform.TransformerFactory</tt> must be set
73
 * to one of the following values.
74
 *
75
 * <blockquote> <table border="1" cellspacing="0" cellpadding="3"> <tr> <td>jd.xslt</td>
76
 * <td>jd.xml.xslt.trax.TransformerFactoryImpl</td> </tr>
77
 *
78
 * <tr> <td>Saxon</td> <td>net.sf.saxon.TransformerFactoryImpl</td> </tr>
79
 *
80
 * <tr> <td>Caucho</td> <td>com.caucho.xsl.Xsl</td> </tr>
81
 *
82
 * <tr> <td>Xalan interpeter</td> <td>org.apache.xalan.processor.TransformerFactory</td>
83
 * </tr>
84
 *
85
 * <tr> <td>Xalan xsltc</td> <td>org.apache.xalan.xsltc.trax.TransformerFactoryImpl</td>
86
 * </tr> </table> </blockquote>
87
 *
88
 * @author Eugene Kuleshov
89
 */
90
public class Processor {
91
 
92
    public static final int BYTECODE = 1;
93
 
94
    public static final int MULTI_XML = 2;
95
 
96
    public static final int SINGLE_XML = 3;
97
 
98
    private static final String SINGLE_XML_NAME = "classes.xml";
99
 
100
    private int inRepresentation;
101
 
102
    private int outRepresentation;
103
 
104
    private InputStream input = null;
105
 
106
    private OutputStream output = null;
107
 
108
    private Source xslt = null;
109
 
110
    private boolean computeMax;
111
 
112
    private int n = 0;
113
 
114
    public Processor(
115
        int inRepresenation,
116
        int outRepresentation,
117
        InputStream input,
118
        OutputStream output,
119
        Source xslt)
120
    {
121
        this.inRepresentation = inRepresenation;
122
        this.outRepresentation = outRepresentation;
123
        this.input = input;
124
        this.output = output;
125
        this.xslt = xslt;
126
        this.computeMax = true;
127
    }
128
 
129
    public int process() throws TransformerException, IOException, SAXException
130
    {
131
        ZipInputStream zis = new ZipInputStream(input);
132
        final ZipOutputStream zos = new ZipOutputStream(output);
133
        final OutputStreamWriter osw = new OutputStreamWriter(zos);
134
 
135
        Thread.currentThread()
136
                .setContextClassLoader(getClass().getClassLoader());
137
 
138
        TransformerFactory tf = TransformerFactory.newInstance();
139
        if (!tf.getFeature(SAXSource.FEATURE)
140
                || !tf.getFeature(SAXResult.FEATURE))
141
            return 0;
142
 
143
        SAXTransformerFactory saxtf = (SAXTransformerFactory) tf;
144
        Templates templates = null;
145
        if (xslt != null) {
146
            templates = saxtf.newTemplates(xslt);
147
        }
148
 
149
        // configuring outHandlerFactory
150
        // ///////////////////////////////////////////////////////
151
 
152
        EntryElement entryElement = getEntryElement(zos);
153
 
154
        ContentHandler outDocHandler = null;
155
        switch (outRepresentation) {
156
            case BYTECODE:
157
                outDocHandler = new OutputSlicingHandler(new ASMContentHandlerFactory(zos,
158
                        computeMax),
159
                        entryElement,
160
                        false);
161
                break;
162
 
163
            case MULTI_XML:
164
                outDocHandler = new OutputSlicingHandler(new SAXWriterFactory(osw,
165
                        true),
166
                        entryElement,
167
                        true);
168
                break;
169
 
170
            case SINGLE_XML:
171
                ZipEntry outputEntry = new ZipEntry(SINGLE_XML_NAME);
172
                zos.putNextEntry(outputEntry);
173
                outDocHandler = new SAXWriter(osw, false);
174
                break;
175
 
176
        }
177
 
178
        // configuring inputDocHandlerFactory
179
        // /////////////////////////////////////////////////
180
        ContentHandler inDocHandler = null;
181
        if (templates == null) {
182
            inDocHandler = outDocHandler;
183
        } else {
184
            inDocHandler = new InputSlicingHandler("class",
185
                    outDocHandler,
186
                    new TransformerHandlerFactory(saxtf,
187
                            templates,
188
                            outDocHandler));
189
        }
190
        ContentHandlerFactory inDocHandlerFactory = new SubdocumentHandlerFactory(inDocHandler);
191
 
192
        if (inDocHandler != null && inRepresentation != SINGLE_XML) {
193
            inDocHandler.startDocument();
194
            inDocHandler.startElement("",
195
                    "classes",
196
                    "classes",
197
                    new AttributesImpl());
198
        }
199
 
200
        int i = 0;
201
        ZipEntry ze = null;
202
        while ((ze = zis.getNextEntry()) != null) {
203
            update(ze.getName(), n++);
204
            if (isClassEntry(ze)) {
205
                processEntry(zis, ze, inDocHandlerFactory);
206
            } else {
207
                OutputStream os = entryElement.openEntry(getName(ze));
208
                copyEntry(zis, os);
209
                entryElement.closeEntry();
210
            }
211
 
212
            i++;
213
        }
214
 
215
        if (inDocHandler != null && inRepresentation != SINGLE_XML) {
216
            inDocHandler.endElement("", "classes", "classes");
217
            inDocHandler.endDocument();
218
        }
219
 
220
        if (outRepresentation == SINGLE_XML) {
221
            zos.closeEntry();
222
        }
223
        zos.flush();
224
        zos.close();
225
 
226
        return i;
227
    }
228
 
229
    private void copyEntry(InputStream is, OutputStream os) throws IOException {
230
        if (outRepresentation == SINGLE_XML)
231
            return;
232
 
233
        byte[] buff = new byte[2048];
234
        int i;
235
        while ((i = is.read(buff)) != -1) {
236
            os.write(buff, 0, i);
237
        }
238
    }
239
 
240
    private boolean isClassEntry(ZipEntry ze) {
241
        String name = ze.getName();
242
        return inRepresentation == SINGLE_XML && name.equals(SINGLE_XML_NAME)
243
                || name.endsWith(".class") || name.endsWith(".class.xml");
244
    }
245
 
246
    private void processEntry(
247
        final ZipInputStream zis,
248
        ZipEntry ze,
249
        ContentHandlerFactory handlerFactory)
250
    {
251
        ContentHandler handler = handlerFactory.createContentHandler();
252
        try {
253
 
254
            // if (CODE2ASM.equals(command)) { // read bytecode and process it
255
            // // with TraceClassVisitor
256
            // ClassReader cr = new ClassReader(readEntry(zis, ze));
257
            // cr.accept(new TraceClassVisitor(null, new PrintWriter(os)),
258
            // false);
259
            // }
260
 
261
            boolean singleInputDocument = inRepresentation == SINGLE_XML;
262
            if (inRepresentation == BYTECODE) { // read bytecode and process it
263
                // with handler
264
                ClassReader cr = new ClassReader(readEntry(zis, ze));
265
                cr.accept(new SAXClassAdapter(handler, singleInputDocument),
266
                        false);
267
 
268
            } else { // read XML and process it with handler
269
                XMLReader reader = XMLReaderFactory.createXMLReader();
270
                reader.setContentHandler(handler);
271
                reader.parse(new InputSource(singleInputDocument
272
                        ? (InputStream) new ProtectedInputStream(zis)
273
                        : new ByteArrayInputStream(readEntry(zis, ze))));
274
 
275
            }
276
        } catch (Exception ex) {
277
            update(ze.getName(), 0);
278
            update(ex, 0);
279
        }
280
    }
281
 
282
    private EntryElement getEntryElement(ZipOutputStream zos) {
283
        if (outRepresentation == SINGLE_XML) {
284
            return new SingleDocElement(zos);
285
        }
286
        return new ZipEntryElement(zos);
287
    }
288
 
289
    // private ContentHandlerFactory getHandlerFactory(
290
    // OutputStream os,
291
    // SAXTransformerFactory saxtf,
292
    // Templates templates)
293
    // {
294
    // ContentHandlerFactory factory = null;
295
    // if (templates == null) {
296
    // if (outputRepresentation == BYTECODE) { // factory used to write
297
    // // bytecode
298
    // factory = new ASMContentHandlerFactory(os, computeMax);
299
    // } else { // factory used to write XML
300
    // factory = new SAXWriterFactory(os, true);
301
    // }
302
    // } else {
303
    // if (outputRepresentation == BYTECODE) { // factory used to transform
304
    // // and then write bytecode
305
    // factory = new ASMTransformerHandlerFactory(saxtf,
306
    // templates,
307
    // os,
308
    // computeMax);
309
    // } else { // factory used to transformand then write XML
310
    // factory = new TransformerHandlerFactory(saxtf,
311
    // templates,
312
    // os,
313
    // outputRepresentation == SINGLE_XML);
314
    // }
315
    // }
316
    // return factory;
317
    // }
318
 
319
    private String getName(ZipEntry ze) {
320
        String name = ze.getName();
321
        if (isClassEntry(ze)) {
322
            if (inRepresentation != BYTECODE && outRepresentation == BYTECODE) {
323
                name = name.substring(0, name.length() - 4); // .class.xml to
324
                // .class
325
            } else if (inRepresentation == BYTECODE
326
                    && outRepresentation != BYTECODE)
327
            {
328
                name = name.concat(".xml"); // .class to .class.xml
329
            }
330
            // } else if( CODE2ASM.equals( command)) {
331
            // name = name.substring( 0, name.length()-6).concat( ".asm");
332
        }
333
        return name;
334
    }
335
 
336
    private byte[] readEntry(ZipInputStream zis, ZipEntry ze)
337
            throws IOException
338
    {
339
        long size = ze.getSize();
340
        if (size > -1) {
341
            byte[] buff = new byte[(int) size];
342
            int k = 0;
343
            int n;
344
            while(( n = zis.read(buff, k, buff.length-k)) > 0) {
345
              k += n;
346
            }
347
            return buff;
348
        }
349
 
350
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
351
        byte[] buff = new byte[4096];
352
        int i;
353
        while ((i = zis.read(buff)) != -1) {
354
            bos.write(buff, 0, i);
355
        }
356
        return bos.toByteArray();
357
    }
358
 
359
    /*
360
     * (non-Javadoc)
361
     *
362
     * @see java.util.Observer#update(java.util.Observable, java.lang.Object)
363
     */
364
    protected void update(Object arg, int n) {
365
        if (arg instanceof Throwable) {
366
            ((Throwable) arg).printStackTrace();
367
        } else {
368
            if ((n % 100) == 0) {
369
                System.err.println(n + " " + arg);
370
            }
371
        }
372
    }
373
 
374
    public static void main(String[] args) throws Exception {
375
        if (args.length < 2) {
376
            showUsage();
377
            return;
378
        }
379
 
380
        int inRepresentation = getRepresentation(args[0]);
381
        int outRepresentation = getRepresentation(args[1]);
382
 
383
        InputStream is = System.in;
384
        OutputStream os = new BufferedOutputStream(System.out);
385
 
386
        Source xslt = null;
387
        // boolean computeMax = true;
388
 
389
        for (int i = 2; i < args.length; i++) {
390
            if ("-in".equals(args[i])) {
391
                is = new FileInputStream(args[++i]);
392
 
393
            } else if ("-out".equals(args[i])) {
394
                os = new BufferedOutputStream(new FileOutputStream(args[++i]));
395
 
396
            } else if ("-xslt".equals(args[i])) {
397
                xslt = new StreamSource(new FileInputStream(args[++i]));
398
 
399
                // } else if( "-computemax".equals( args[ i].toLowerCase())) {
400
                // computeMax = true;
401
 
402
            } else {
403
                showUsage();
404
                return;
405
 
406
            }
407
        }
408
 
409
        if (inRepresentation == 0 || outRepresentation == 0) {
410
            showUsage();
411
            return;
412
        }
413
 
414
        Processor m = new Processor(inRepresentation,
415
                outRepresentation,
416
                is,
417
                os,
418
                xslt);
419
 
420
        long l1 = System.currentTimeMillis();
421
        int n = m.process();
422
        long l2 = System.currentTimeMillis();
423
        System.err.println(n);
424
        System.err.println("" + (l2 - l1) + "ms  " + (1000f * n / (l2 - l1))
425
                + " resources/sec");
426
    }
427
 
428
    private static int getRepresentation(String s) {
429
        if ("code".equals(s)) {
430
            return BYTECODE;
431
        } else if ("xml".equals(s)) {
432
            return MULTI_XML;
433
        } else if ("singlexml".equals(s)) {
434
            return SINGLE_XML;
435
        }
436
        return 0;
437
    }
438
 
439
    private static void showUsage() {
440
        System.err.println("Usage: Main <in format> <out format> [-in <input jar>] [-out <output jar>] [-xslt <xslt file>]");
441
        System.err.println("  when -in or -out is omitted sysin and sysout would be used");
442
        System.err.println("  <in format> and <out format> - code | xml | singlexml");
443
    }
444
 
445
    /**
446
     * IputStream wrapper class used to protect input streams from being closed
447
     * by some stupid XML parsers.
448
     */
449
    private static final class ProtectedInputStream extends InputStream {
450
        private final InputStream is;
451
 
452
        private ProtectedInputStream(InputStream is) {
453
            super();
454
            this.is = is;
455
        }
456
 
457
        public final void close() throws IOException {
458
        }
459
 
460
        public final int read() throws IOException {
461
            return is.read();
462
        }
463
 
464
        public final int read(byte[] b, int off, int len) throws IOException {
465
            return is.read(b, off, len);
466
        }
467
 
468
        public final int available() throws IOException {
469
            return is.available();
470
        }
471
    }
472
 
473
    /**
474
     * A {@link ContentHandlerFactory ContentHandlerFactory} is used to create
475
     * {@link org.xml.sax.ContentHandler ContentHandler} instances for concrete
476
     * context.
477
     */
478
    private static interface ContentHandlerFactory {
479
 
480
        /**
481
         * Creates an instance of the content handler.
482
         *
483
         * @return content handler
484
         */
485
        ContentHandler createContentHandler();
486
 
487
    }
488
 
489
    /**
490
     * SAXWriterFactory
491
     */
492
    private static final class SAXWriterFactory implements
493
            ContentHandlerFactory
494
    {
495
        private Writer w;
496
 
497
        private boolean optimizeEmptyElements;
498
 
499
        public SAXWriterFactory(Writer w, boolean optimizeEmptyElements) {
500
            this.w = w;
501
            this.optimizeEmptyElements = optimizeEmptyElements;
502
        }
503
 
504
        public final ContentHandler createContentHandler() {
505
            return new SAXWriter(w, optimizeEmptyElements);
506
        }
507
 
508
    }
509
 
510
    /**
511
     * ASMContentHandlerFactory
512
     */
513
    private static final class ASMContentHandlerFactory implements
514
            ContentHandlerFactory
515
    {
516
        private OutputStream os;
517
 
518
        private boolean computeMax;
519
 
520
        public ASMContentHandlerFactory(OutputStream os, boolean computeMax) {
521
            this.os = os;
522
            this.computeMax = computeMax;
523
        }
524
 
525
        public final ContentHandler createContentHandler() {
526
            return new ASMContentHandler(os, computeMax);
527
        }
528
 
529
    }
530
 
531
    /**
532
     * TransformerHandlerFactory
533
     */
534
    private static final class TransformerHandlerFactory implements
535
            ContentHandlerFactory
536
    {
537
        private SAXTransformerFactory saxtf;
538
 
539
        private Templates templates;
540
 
541
        private ContentHandler outputHandler;
542
 
543
        public TransformerHandlerFactory(
544
            SAXTransformerFactory saxtf,
545
            Templates templates,
546
            ContentHandler outputHandler)
547
        {
548
            this.saxtf = saxtf;
549
            this.templates = templates;
550
            this.outputHandler = outputHandler;
551
        }
552
 
553
        public final ContentHandler createContentHandler() {
554
            try {
555
                TransformerHandler handler = saxtf.newTransformerHandler(templates);
556
                handler.setResult(new SAXResult(outputHandler));
557
                return handler;
558
            } catch (TransformerConfigurationException ex) {
559
                throw new RuntimeException(ex.toString());
560
            }
561
        }
562
    }
563
 
564
    /**
565
     * SubdocumentHandlerFactory
566
     */
567
    private final static class SubdocumentHandlerFactory implements
568
            ContentHandlerFactory
569
    {
570
        private ContentHandler subdocumentHandler;
571
 
572
        public SubdocumentHandlerFactory(ContentHandler subdocumentHandler) {
573
            this.subdocumentHandler = subdocumentHandler;
574
        }
575
 
576
        public final ContentHandler createContentHandler() {
577
            return subdocumentHandler;
578
        }
579
 
580
    }
581
 
582
    /**
583
     * A {@link org.xml.sax.ContentHandler ContentHandler} and
584
     * {@link org.xml.sax.ext.LexicalHandler LexicalHandler} that serializes XML
585
     * from SAX 2.0 events into {@link java.io.Writer Writer}.
586
     *
587
     * <i><blockquote> This implementation does not support namespaces, entity
588
     * definitions (uncluding DTD), CDATA and text elements. </blockquote></i>
589
     */
590
    private final static class SAXWriter extends DefaultHandler implements
591
            LexicalHandler
592
    {
593
        private static final char[] OFF = "                                                                                                        ".toCharArray();
594
 
595
        private Writer w;
596
 
597
        private boolean optimizeEmptyElements;
598
 
599
        private boolean openElement = false;
600
 
601
        private int ident = 0;
602
 
603
        /**
604
         * Creates <code>SAXWriter</code>.
605
         *
606
         * @param w writer
607
         * @param optimizeEmptyElements if set to <code>true</code>, short
608
         *        XML syntax will be used for empty elements
609
         */
610
        public SAXWriter(Writer w, boolean optimizeEmptyElements) {
611
            this.w = w;
612
            this.optimizeEmptyElements = optimizeEmptyElements;
613
        }
614
 
615
        public final void startElement(
616
            String ns,
617
            String localName,
618
            String qName,
619
            Attributes atts) throws SAXException
620
        {
621
            try {
622
                closeElement();
623
 
624
                writeIdent();
625
                w.write("<".concat(qName));
626
                if (atts != null && atts.getLength() > 0)
627
                    writeAttributes(atts);
628
 
629
                if (!optimizeEmptyElements) {
630
                    w.write(">\n");
631
                } else {
632
                    openElement = true;
633
                }
634
                ident += 2;
635
 
636
            } catch (IOException ex) {
637
                throw new SAXException(ex);
638
 
639
            }
640
        }
641
 
642
        public final void endElement(String ns, String localName, String qName)
643
                throws SAXException
644
        {
645
            ident -= 2;
646
            try {
647
                if (openElement) {
648
                    w.write("/>\n");
649
                    openElement = false;
650
                } else {
651
                    writeIdent();
652
                    w.write("</" + qName + ">\n");
653
                }
654
 
655
            } catch (IOException ex) {
656
                throw new SAXException(ex);
657
 
658
            }
659
        }
660
 
661
        public final void endDocument() throws SAXException {
662
            try {
663
                w.flush();
664
 
665
            } catch (IOException ex) {
666
                throw new SAXException(ex);
667
 
668
            }
669
        }
670
 
671
        public final void comment(char[] ch, int off, int len)
672
                throws SAXException
673
        {
674
            try {
675
                closeElement();
676
 
677
                writeIdent();
678
                w.write("<!-- ");
679
                w.write(ch, off, len);
680
                w.write(" -->\n");
681
 
682
            } catch (IOException ex) {
683
                throw new SAXException(ex);
684
 
685
            }
686
        }
687
 
688
        public final void startDTD(String arg0, String arg1, String arg2)
689
                throws SAXException
690
        {
691
        }
692
 
693
        public final void endDTD() throws SAXException {
694
        }
695
 
696
        public final void startEntity(String arg0) throws SAXException {
697
        }
698
 
699
        public final void endEntity(String arg0) throws SAXException {
700
        }
701
 
702
        public final void startCDATA() throws SAXException {
703
        }
704
 
705
        public final void endCDATA() throws SAXException {
706
        }
707
 
708
        private final void writeAttributes(Attributes atts) throws IOException {
709
            StringBuffer sb = new StringBuffer();
710
            int len = atts.getLength();
711
            for (int i = 0; i < len; i++) {
712
                sb.append(" ")
713
                        .append(atts.getLocalName(i))
714
                        .append("=\"")
715
                        .append(esc(atts.getValue(i)))
716
                        .append("\"");
717
            }
718
            w.write(sb.toString());
719
        }
720
 
721
        /**
722
         * Encode string with escaping.
723
         *
724
         * @param str string to encode.
725
         * @return encoded string
726
         */
727
        private final String esc(String str) {
728
            StringBuffer sb = new StringBuffer(str.length());
729
            for (int i = 0; i < str.length(); i++) {
730
                char ch = str.charAt(i);
731
                switch (ch) {
732
                    case '&':
733
                        sb.append("&amp;");
734
                        break;
735
 
736
                    case '<':
737
                        sb.append("&lt;");
738
                        break;
739
 
740
                    case '>':
741
                        sb.append("&gt;");
742
                        break;
743
 
744
                    case '\"':
745
                        sb.append("&quot;");
746
                        break;
747
 
748
                    default:
749
                        if (ch > 0x7f) {
750
                            sb.append("&#")
751
                                    .append(Integer.toString(ch))
752
                                    .append(';');
753
                        } else {
754
                            sb.append(ch);
755
                        }
756
 
757
                }
758
            }
759
            return sb.toString();
760
        }
761
 
762
        private final void writeIdent() throws IOException {
763
            int n = ident;
764
            while (n > 0) {
765
                if (n > OFF.length) {
766
                    w.write(OFF);
767
                    n -= OFF.length;
768
                } else {
769
                    w.write(OFF, 0, n);
770
                    n = 0;
771
                }
772
            }
773
        }
774
 
775
        private final void closeElement() throws IOException {
776
            if (openElement) {
777
                w.write(">\n");
778
            }
779
            openElement = false;
780
        }
781
 
782
    }
783
 
784
    /**
785
     * A {@link org.xml.sax.ContentHandler ContentHandler} that splits XML
786
     * documents into smaller chunks. Each chunk is processed by the nested
787
     * {@link org.xml.sax.ContentHandler ContentHandler} obtained from
788
     * {@link java.net.ContentHandlerFactory ContentHandlerFactory}. This is
789
     * useful for running XSLT engine against large XML document that will
790
     * hardly fit into the memory all together. <p> TODO use complete path for
791
     * subdocumentRoot
792
     */
793
    private final static class InputSlicingHandler extends DefaultHandler {
794
        private String subdocumentRoot;
795
 
796
        private ContentHandler rootHandler;
797
 
798
        private ContentHandlerFactory subdocumentHandlerFactory;
799
 
800
        private boolean subdocument = false;
801
 
802
        private ContentHandler subdocumentHandler;
803
 
804
        /**
805
         * Constructs a new {@link InputSlicingHandler SubdocumentHandler}
806
         * object.
807
         *
808
         * @param subdocumentRoot name/path to the root element of the
809
         *        subdocument
810
         * @param rootHandler content handler for the entire document
811
         *        (subdocument envelope).
812
         * @param subdocumentHandlerFactory a
813
         *        {@link ContentHandlerFactory ContentHandlerFactory} used to
814
         *        create {@link ContentHandler ContentHandler} instances for
815
         *        subdocuments.
816
         */
817
        public InputSlicingHandler(
818
            String subdocumentRoot,
819
            ContentHandler rootHandler,
820
            ContentHandlerFactory subdocumentHandlerFactory)
821
        {
822
            this.subdocumentRoot = subdocumentRoot;
823
            this.rootHandler = rootHandler;
824
            this.subdocumentHandlerFactory = subdocumentHandlerFactory;
825
        }
826
 
827
        public final void startElement(
828
            String namespaceURI,
829
            String localName,
830
            String qName,
831
            Attributes list) throws SAXException
832
        {
833
            if (subdocument) {
834
                subdocumentHandler.startElement(namespaceURI,
835
                        localName,
836
                        qName,
837
                        list);
838
            } else if (localName.equals(subdocumentRoot)) {
839
                subdocumentHandler = subdocumentHandlerFactory.createContentHandler();
840
                subdocumentHandler.startDocument();
841
                subdocumentHandler.startElement(namespaceURI,
842
                        localName,
843
                        qName,
844
                        list);
845
                subdocument = true;
846
            } else if (rootHandler != null) {
847
                rootHandler.startElement(namespaceURI, localName, qName, list);
848
            }
849
        }
850
 
851
        public final void endElement(
852
            String namespaceURI,
853
            String localName,
854
            String qName) throws SAXException
855
        {
856
            if (subdocument) {
857
                subdocumentHandler.endElement(namespaceURI, localName, qName);
858
                if (localName.equals(subdocumentRoot)) {
859
                    subdocumentHandler.endDocument();
860
                    subdocument = false;
861
                }
862
            } else if (rootHandler != null) {
863
                rootHandler.endElement(namespaceURI, localName, qName);
864
            }
865
        }
866
 
867
        public final void startDocument() throws SAXException {
868
            if (rootHandler != null) {
869
                rootHandler.startDocument();
870
            }
871
        }
872
 
873
        public final void endDocument() throws SAXException {
874
            if (rootHandler != null) {
875
                rootHandler.endDocument();
876
 
877
            }
878
        }
879
 
880
        public final void characters(char[] buff, int offset, int size)
881
                throws SAXException
882
        {
883
            if (subdocument) {
884
                subdocumentHandler.characters(buff, offset, size);
885
            } else if (rootHandler != null) {
886
                rootHandler.characters(buff, offset, size);
887
            }
888
        }
889
 
890
    }
891
 
892
    /**
893
     * A {@link org.xml.sax.ContentHandler ContentHandler} that splits XML
894
     * documents into smaller chunks. Each chunk is processed by the nested
895
     * {@link org.xml.sax.ContentHandler ContentHandler} obtained from
896
     * {@link java.net.ContentHandlerFactory ContentHandlerFactory}. This is
897
     * useful for running XSLT engine against large XML document that will
898
     * hardly fit into the memory all together. <p> TODO use complete path for
899
     * subdocumentRoot
900
     */
901
    private static final class OutputSlicingHandler extends DefaultHandler {
902
        private String subdocumentRoot;
903
 
904
        private ContentHandlerFactory subdocumentHandlerFactory;
905
 
906
        private EntryElement entryElement;
907
 
908
        private boolean isXml;
909
 
910
        private boolean subdocument = false;
911
 
912
        private ContentHandler subdocumentHandler;
913
 
914
        /**
915
         * Constructs a new {@link OutputSlicingHandler SubdocumentHandler}
916
         * object.
917
         *
918
         * @param subdocumentHandlerFactory a
919
         *        {@link ContentHandlerFactory ContentHandlerFactory} used to
920
         *        create {@link ContentHandler ContentHandler} instances for
921
         *        subdocuments.
922
         * @param entryElement TODO.
923
         * @param isXml TODO.
924
         */
925
        public OutputSlicingHandler(
926
            ContentHandlerFactory subdocumentHandlerFactory,
927
            EntryElement entryElement,
928
            boolean isXml)
929
        {
930
            this.subdocumentRoot = "class";
931
            this.subdocumentHandlerFactory = subdocumentHandlerFactory;
932
            this.entryElement = entryElement;
933
            this.isXml = isXml;
934
        }
935
 
936
        public final void startElement(
937
            String namespaceURI,
938
            String localName,
939
            String qName,
940
            Attributes list) throws SAXException
941
        {
942
            if (subdocument) {
943
                subdocumentHandler.startElement(namespaceURI,
944
                        localName,
945
                        qName,
946
                        list);
947
            } else if (localName.equals(subdocumentRoot)) {
948
                String name = list.getValue("name");
949
                if (name == null || name.length() == 0)
950
                    throw new SAXException("Class element without name attribute.");
951
                try {
952
                    entryElement.openEntry(isXml
953
                            ? name.concat(".class.xml")
954
                            : name.concat(".class"));
955
                } catch (IOException ex) {
956
                    throw new SAXException(ex.toString(), ex);
957
                }
958
                subdocumentHandler = subdocumentHandlerFactory.createContentHandler();
959
                subdocumentHandler.startDocument();
960
                subdocumentHandler.startElement(namespaceURI,
961
                        localName,
962
                        qName,
963
                        list);
964
                subdocument = true;
965
            }
966
        }
967
 
968
        public final void endElement(
969
            String namespaceURI,
970
            String localName,
971
            String qName) throws SAXException
972
        {
973
            if (subdocument) {
974
                subdocumentHandler.endElement(namespaceURI, localName, qName);
975
                if (localName.equals(subdocumentRoot)) {
976
                    subdocumentHandler.endDocument();
977
                    subdocument = false;
978
                    try {
979
                        entryElement.closeEntry();
980
                    } catch (IOException ex) {
981
                        throw new SAXException(ex.toString(), ex);
982
                    }
983
                }
984
            }
985
        }
986
 
987
        public final void startDocument() throws SAXException {
988
        }
989
 
990
        public final void endDocument() throws SAXException {
991
        }
992
 
993
        public final void characters(char[] buff, int offset, int size)
994
                throws SAXException
995
        {
996
            if (subdocument) {
997
                subdocumentHandler.characters(buff, offset, size);
998
            }
999
        }
1000
 
1001
    }
1002
 
1003
    private static interface EntryElement {
1004
 
1005
        OutputStream openEntry(String name) throws IOException;
1006
 
1007
        void closeEntry() throws IOException;
1008
 
1009
    }
1010
 
1011
    private static final class SingleDocElement implements EntryElement {
1012
        private OutputStream os;
1013
 
1014
        public SingleDocElement(OutputStream os) {
1015
            this.os = os;
1016
        }
1017
 
1018
        public OutputStream openEntry(String name) throws IOException {
1019
            return os;
1020
        }
1021
 
1022
        public void closeEntry() throws IOException {
1023
            os.flush();
1024
        }
1025
 
1026
    }
1027
 
1028
    private static final class ZipEntryElement implements EntryElement {
1029
        private ZipOutputStream zos;
1030
 
1031
        public ZipEntryElement(ZipOutputStream zos) {
1032
            this.zos = zos;
1033
        }
1034
 
1035
        public OutputStream openEntry(String name) throws IOException {
1036
            ZipEntry entry = new ZipEntry(name);
1037
            zos.putNextEntry(entry);
1038
            return zos;
1039
        }
1040
 
1041
        public void closeEntry() throws IOException {
1042
            zos.flush();
1043
            zos.closeEntry();
1044
        }
1045
 
1046
    }
1047
 
1048
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.