1 /**
2 * Copyright 2011 meltmedia
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package org.xchain.framework.sax;
17
18 import java.util.Map;
19 import java.util.HashMap;
20 import java.util.HashSet;
21 import java.util.Set;
22 import java.util.LinkedList;
23
24 /**
25 * The <code>PrefixMapping</code> class keeps track of the current NamespaceURI for a Prefix. The NamespaceURIs for a Prefix are kept in a stack.
26 * When a new NamespaceURI is added for a Prefix it will be added to the top of the stack. The Prefix will then resolve to that
27 * NamespaceURI until the NamespaceURI is either popped or a new NamespaceURI is added. If the NamespaceURI is popped then the
28 * previous NamespaceURI registered for that Prefix will be resolved for the Prefix. If there was no previous NamespaceURI
29 * registered for the Prefix then the Prefix will resolve to <code>null</code>.
30 *
31 * @author Christian Trimble
32 */
33 public class ReversePrefixMappingContext
34 extends PrefixMappingContext
35 {
36 // The Prefix to NamespaceURI list mapping.
37 protected Map<String, LinkedList<String>> namespaceMap = new HashMap<String, LinkedList<String>>();
38
39 public ReversePrefixMappingContext()
40 {
41 }
42
43 private void removeMapping( String prefix, String namespaceUri )
44 {
45 LinkedList<String> prefixList = namespaceMap.get(namespaceUri);
46 if( prefixList != null ) {
47 int firstIndex = prefixList.indexOf(prefix);
48 if( firstIndex >= 0 ) {
49 prefixList.remove(firstIndex);
50 if( prefixList.isEmpty() ) {
51 namespaceMap.remove(namespaceUri);
52 }
53 }
54 }
55 }
56
57 private void addMapping( String prefix, String namespaceUri )
58 {
59 LinkedList<String> prefixList = namespaceMap.get(namespaceUri);
60 if( prefixList == null ) {
61 namespaceMap.put(namespaceUri, prefixList = new LinkedList<String>());
62 }
63 prefixList.addFirst(prefix);
64 }
65
66 public void startDocument()
67 {
68 super.startDocument();
69 }
70
71 public void endDocument()
72 {
73 super.endDocument();
74 }
75
76 public void startPrefixMapping( String prefix, String namespaceUri )
77 {
78 super.startPrefixMapping( prefix, namespaceUri );
79 addMapping(prefix, namespaceUri);
80 }
81
82 /**
83 * Ends the mapping for the specified prefix.
84 */
85 public void endPrefixMapping( String prefix )
86 {
87 // get the current namespace for this prefix.
88 String currentNamespaceUri = prefixMap.get(prefix).getFirst();
89
90 // end the prefix with the parent class.
91 super.endPrefixMapping( prefix );
92
93 // remove the mapping for the prefix.
94 removeMapping( prefix, currentNamespaceUri );
95 }
96
97 /**
98 * Find the current NamespaceURI for the Prefix.
99 *
100 * @param namespaceUri The Namespace URI to lookup.
101 *
102 * @return The current NamespaceURI for the Prefix if found. Null if there is no current NamespaceURI for the Prefix.
103 */
104 public String lookUpPrefix( String namespaceUri )
105 {
106 LinkedList<String> prefixList = namespaceMap.get(namespaceUri);
107
108 if( prefixList == null ) {
109 return null;
110 }
111 else {
112 return prefixList.getFirst();
113 }
114 }
115 }