001: /*
002: * Copyright 2006 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: package com.sun.xml.internal.bind.v2.runtime;
027:
028: import java.util.HashMap;
029: import java.util.HashSet;
030: import java.util.Map;
031: import java.util.Set;
032:
033: import javax.xml.namespace.QName;
034:
035: import com.sun.xml.internal.bind.v2.util.QNameMap;
036:
037: /**
038: * Creates {@link Name}s and assign index numbers to them.
039: *
040: * <p>
041: * During this process, this class also finds out which namespace URIs
042: * are statically known to be un-bindable as the default namespace.
043: * Those are the namespace URIs that are used by attribute names.
044: *
045: * @author Kohsuke Kawaguchi
046: */
047: @SuppressWarnings({"StringEquality"})
048: public final class NameBuilder {
049: private Map<String, Integer> uriIndexMap = new HashMap<String, Integer>();
050: private Set<String> nonDefaultableNsUris = new HashSet<String>();
051: private Map<String, Integer> localNameIndexMap = new HashMap<String, Integer>();
052: private QNameMap<Integer> elementQNameIndexMap = new QNameMap<Integer>();
053: private QNameMap<Integer> attributeQNameIndexMap = new QNameMap<Integer>();
054:
055: public Name createElementName(QName name) {
056: return createElementName(name.getNamespaceURI(), name
057: .getLocalPart());
058: }
059:
060: public Name createElementName(String nsUri, String localName) {
061: return createName(nsUri, localName, false, elementQNameIndexMap);
062: }
063:
064: public Name createAttributeName(QName name) {
065: return createAttributeName(name.getNamespaceURI(), name
066: .getLocalPart());
067: }
068:
069: public Name createAttributeName(String nsUri, String localName) {
070: assert nsUri.intern() == nsUri;
071: assert localName.intern() == localName;
072:
073: if (nsUri.length() == 0)
074: return new Name(allocIndex(attributeQNameIndexMap, "",
075: localName), -1, nsUri, allocIndex(
076: localNameIndexMap, localName), localName, true);
077: else {
078: nonDefaultableNsUris.add(nsUri);
079: return createName(nsUri, localName, true,
080: attributeQNameIndexMap);
081: }
082: }
083:
084: private Name createName(String nsUri, String localName,
085: boolean isAttribute, QNameMap<Integer> map) {
086: assert nsUri.intern() == nsUri;
087: assert localName.intern() == localName;
088:
089: return new Name(allocIndex(map, nsUri, localName), allocIndex(
090: uriIndexMap, nsUri), nsUri, allocIndex(
091: localNameIndexMap, localName), localName, isAttribute);
092: }
093:
094: private int allocIndex(Map<String, Integer> map, String str) {
095: Integer i = map.get(str);
096: if (i == null) {
097: i = map.size();
098: map.put(str, i);
099: }
100: return i;
101: }
102:
103: private int allocIndex(QNameMap<Integer> map, String nsUri,
104: String localName) {
105: Integer i = map.get(nsUri, localName);
106: if (i == null) {
107: i = map.size();
108: map.put(nsUri, localName, i);
109: }
110: return i;
111: }
112:
113: /**
114: * Wraps up everything and creates {@link NameList}.
115: */
116: public NameList conclude() {
117: boolean[] nsUriCannotBeDefaulted = new boolean[uriIndexMap
118: .size()];
119: for (Map.Entry<String, Integer> e : uriIndexMap.entrySet()) {
120: nsUriCannotBeDefaulted[e.getValue()] = nonDefaultableNsUris
121: .contains(e.getKey());
122: }
123:
124: NameList r = new NameList(list(uriIndexMap),
125: nsUriCannotBeDefaulted, list(localNameIndexMap),
126: elementQNameIndexMap.size(), attributeQNameIndexMap
127: .size());
128: // delete them so that the create method can never be called again
129: uriIndexMap = null;
130: localNameIndexMap = null;
131: return r;
132: }
133:
134: private String[] list(Map<String, Integer> map) {
135: String[] r = new String[map.size()];
136: for (Map.Entry<String, Integer> e : map.entrySet())
137: r[e.getValue()] = e.getKey();
138: return r;
139: }
140: }
|