xref: /trunk/main/ooxml/source/framework/SchemaParser/src/org/apache/openoffice/ooxml/schema/model/schema/NamespaceMap.java (revision 3309286857f19787ae62bd793a98b5af4edd2ad3)
1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements.  See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership.  The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License.  You may obtain a copy of the License at
10 *
11 *   http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied.  See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21 
22 package org.apache.openoffice.ooxml.schema.model.schema;
23 
24 import java.util.HashMap;
25 import java.util.Iterator;
26 import java.util.Map;
27 import java.util.Map.Entry;
28 import java.util.TreeMap;
29 
30 /** Map between namespace prefixes and URIs.
31  *  While namespace URIs can have different prefixes in different schemas,
32  *  we will use only one prefix in the OOXML parser.  This class
33  *  provides these global prefixes.
34  */
35 public class NamespaceMap
36     implements Iterable<Entry<String, String>>
37 {
NamespaceMap()38     public NamespaceMap ()
39     {
40         maURIToPrefixMap = new HashMap<>(maPredefinedURIToPrefixMap);
41 
42         // Predefine namespace prefixes.
43         // If possible then use the ones already in use in the schema files or documents written by MS Office,
44         // appended with a 06 or 12 for the ECMA-376 standards of 2006 (1st edition) or 2012 (4th edition).
45         maURIToPrefixMap.put("http://schemas.openxmlformats.org/drawingml/2006/main", "a06");
46         maURIToPrefixMap.put("http://purl.oclc.org/ooxml/drawingml/main", "a12");
47 
48         maURIToPrefixMap.put("http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing", "wp06");
49         maURIToPrefixMap.put("http://purl.oclc.org/ooxml/drawingml/wordprocessingDrawing", "wp12");
50 
51         maURIToPrefixMap.put("http://schemas.openxmlformats.org/wordprocessingml/2006/main", "w06");
52         maURIToPrefixMap.put("http://purl.oclc.org/ooxml/wordprocessingml/main", "w12");
53 
54         maURIToPrefixMap.put("http://schemas.openxmlformats.org/drawingml/2006/picture", "dpct06");
55         maURIToPrefixMap.put("http://purl.oclc.org/ooxml/drawingml/picture", "dpct12");
56 
57         maURIToPrefixMap.put("http://schemas.openxmlformats.org/officeDocument/2006/math", "m06");
58         maURIToPrefixMap.put("http://purl.oclc.org/ooxml/officeDocument/math", "m12");
59 
60         maURIToPrefixMap.put("http://schemas.openxmlformats.org/officeDocument/2006/relationships", "r06");
61         maURIToPrefixMap.put("http://purl.oclc.org/ooxml/officeDocument/relationships", "r12");
62 
63         // Invent prefixes that are not in use.
64         maURIToPrefixMap.put("http://schemas.openxmlformats.org/spreadsheetml/2006/main", "s06");
65         maURIToPrefixMap.put("http://purl.oclc.org/ooxml/spreadsheetml/main", "s12");
66 
67         maURIToPrefixMap.put("http://schemas.openxmlformats.org/presentationml/2006/main", "p06");
68         maURIToPrefixMap.put("http://purl.oclc.org/ooxml/presentationml/main", "p12");
69 
70         maURIToPrefixMap.put("http://schemas.openxmlformats.org/schemaLibrary/2006/main", "sl06");
71         maURIToPrefixMap.put("http://purl.oclc.org/ooxml/schemaLibrary/main", "sl12");
72 
73         maURIToPrefixMap.put("http://purl.oclc.org/ooxml/drawingml/diagram", "dd12");
74         maURIToPrefixMap.put("http://purl.oclc.org/ooxml/drawingml/chart", "dc12");
75         maURIToPrefixMap.put("http://purl.oclc.org/ooxml/drawingml/lockedCanvas", "dlc12");
76     }
77 
78 
79 
80 
ProvideNamespace( final String sNamespaceURI, final String sDefaultPrefix)81     public void ProvideNamespace (
82         final String sNamespaceURI,
83         final String sDefaultPrefix)
84     {
85         if ( ! maURIToPrefixMap.containsKey(sNamespaceURI))
86         {
87             final String sPrefix;
88             // Check if we can use the given prefix.
89             if (sDefaultPrefix==null || IsPrefixUsed(sDefaultPrefix))
90             {
91                 // Prefix is already used.  We have to create a new and unique one.
92                 String sCandidate = null;
93                 for (int nIndex=0; nIndex<=26; ++nIndex)
94                 {
95                     if (nIndex == 26)
96                         throw new RuntimeException("can not invent more than 26 namespace names");
97                     sCandidate= new String(new byte[]{(byte)('A'+nIndex)});
98                     if ( ! maURIToPrefixMap.containsKey(sCandidate))
99                         break;
100                 }
101                 sPrefix = sCandidate;
102             }
103             else
104             {
105                 // Use the given prefix.
106                 sPrefix = sDefaultPrefix;
107             }
108 
109             maURIToPrefixMap.put(sNamespaceURI, sPrefix);
110         }
111     }
112 
113 
114 
115 
GetNamespacePrefix(final String sURI)116     public String GetNamespacePrefix (final String sURI)
117     {
118         return maURIToPrefixMap.get(sURI);
119     }
120 
121 
122 
123 
iterator()124     public Iterator<Entry<String,String>> iterator ()
125     {
126         return maURIToPrefixMap.entrySet().iterator();
127     }
128 
129 
130 
131 
GetCount()132     public Object GetCount()
133     {
134         return maURIToPrefixMap.size();
135     }
136 
137 
138 
139 
140     /** Return all namespace entries sorted on the prefix.
141      */
GetSorted()142     public Iterable<Entry<String,String>> GetSorted ()
143     {
144         final Map<String,Entry<String,String>> aSortedEntries = new TreeMap<>();
145         for (final Entry<String,String> aEntry : maURIToPrefixMap.entrySet())
146             if (aEntry.getValue() == null)
147                 aSortedEntries.put("", aEntry);
148             else
149                 aSortedEntries.put(aEntry.getValue(), aEntry);
150         return aSortedEntries.values();
151     }
152 
153 
154 
155 
IsPrefixUsed(final String sPrefix)156     private boolean IsPrefixUsed (final String sPrefix)
157     {
158         for (final String sUsedPrefix : maURIToPrefixMap.values())
159         {
160             if (sUsedPrefix == null)
161                 continue;
162             if (sUsedPrefix.equals(sPrefix))
163                 return true;
164         }
165         return false;
166     }
167 
168 
169 
170 
171     private final Map<String,String> maURIToPrefixMap;
172     private final static Map<String,String> maPredefinedURIToPrefixMap;
173     static
174     {
175         maPredefinedURIToPrefixMap =  new HashMap<>();
176         maPredefinedURIToPrefixMap.put("http://www.w3.org/2001/XMLSchema", "xsd");
177     }
178 }
179