summaryrefslogtreecommitdiffstats
path: root/sca-java-1.x/branches/sca-java-1.6.2/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/TuscanyXMLStreamReader.java
blob: e1b218d9f47280578ed5342fc581d1b6ecec1ea9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
package org.apache.tuscany.sca.contribution.processor;

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.    
 */
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;

import javax.xml.XMLConstants;
import javax.xml.namespace.NamespaceContext;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.util.StreamReaderDelegate;

/*
 * Custom implementaion of the XMLStreamReader to keep track of the namespace context for each element
 */
public class TuscanyXMLStreamReader extends StreamReaderDelegate implements XMLStreamReader {

    Stack<List<String>[]> context = new Stack<List<String>[]>();

    String characterEncodingScheme;
    List<String>[] contextList;
    List<String> prefixList;
    List<String> uriList;

    public TuscanyXMLStreamReader(XMLStreamReader reader) {
        super(reader);
        this.saveCharacterEncodingScheme();
    }

    public void pushContext() throws XMLStreamException {
        contextList = new List[2];
        prefixList = new ArrayList<String>();
        uriList = new ArrayList<String>();
        int namespaceCount = this.getNamespaceCount();
        for (int i = 0; i < namespaceCount; i++) {
            prefixList.add(checkString(this.getNamespacePrefix(i)));
            uriList.add(this.getNamespaceURI(i));
        }
        contextList[0] = prefixList;
        contextList[1] = uriList;
        context.push(contextList);
    }

    private String checkString(String namespacePrefix) {
        if (namespacePrefix == null) {
            return XMLConstants.DEFAULT_NS_PREFIX;
        } else {
            return namespacePrefix;
        }
    }

    public void popContext() throws XMLStreamException {
        context.pop();
    }
    
    public void saveCharacterEncodingScheme() {
        this.characterEncodingScheme = super.getCharacterEncodingScheme();
    }

    // A flag to indicate if the next() is called from nextTag()
    private boolean withinNextTagMethod = false;
   
    /*
     * Overriding the next() method to perform PUSH and POP operations 
     * for the NamespaceContext for the current element
     */
    @Override
    public int next() throws XMLStreamException {
        // POP the namespaces if the reader leaves the end element
        if (!withinNextTagMethod && this.getEventType() == END_ELEMENT) {
            popContext();
        }

        // get the next event 
        int nextEvent = super.next();
        
        // PUSH the namespaces onto the stack as the reader enters the start element
        if (!withinNextTagMethod && nextEvent == START_ELEMENT) {
            pushContext();
        }
        return nextEvent;
    }

    @Override
    public int nextTag() throws XMLStreamException {
        withinNextTagMethod = true;
        // POP the namespaces out of the stack if the reader leaves the end element
        if (this.getEventType() == END_ELEMENT) {
            popContext();
        }        
        
        // REVIEW: what if nextTag() calls next()?
        int event = super.nextTag();
        
        // PUSH the namespaces onto the stack as the reader enters the start element
        if (event == START_ELEMENT) {
            pushContext();
        }
        withinNextTagMethod = false;
        return event;
    }

    @Override
    public NamespaceContext getNamespaceContext() {
        return new TuscanyNamespaceContext((Stack<List<String>[]>)context.clone());
    }
    

    @Override
    public String getCharacterEncodingScheme() {
        return characterEncodingScheme;
    }
}