001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common Development
008: * and Distribution License("CDDL") (collectively, the "License"). You
009: * may not use this file except in compliance with the License. You can obtain
010: * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
011: * or glassfish/bootstrap/legal/LICENSE.txt. See the License for the specific
012: * language governing permissions and limitations under the License.
013: *
014: * When distributing the software, include this License Header Notice in each
015: * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
016: * Sun designates this particular file as subject to the "Classpath" exception
017: * as provided by Sun in the GPL Version 2 section of the License file that
018: * accompanied this code. If applicable, add the following below the License
019: * Header, with the fields enclosed by brackets [] replaced by your own
020: * identifying information: "Portions Copyrighted [year]
021: * [name of copyright owner]"
022: *
023: * Contributor(s):
024: *
025: * If you wish your version of this file to be governed by only the CDDL or
026: * only the GPL Version 2, indicate your decision by adding "[Contributor]
027: * elects to include this software in this distribution under the [CDDL or GPL
028: * Version 2] license." If you don't indicate a single choice of license, a
029: * recipient has the option to distribute your version of this file under
030: * either the CDDL, the GPL Version 2 or to extend the choice of license to
031: * its licensees as provided above. However, if you add GPL Version 2 code
032: * and therefore, elected the GPL Version 2 license, then the option applies
033: * only if the new code is made subject to such option by the copyright
034: * holder.
035: */
036:
037: package com.sun.xml.bind.v2.runtime.unmarshaller;
038:
039: import javax.xml.namespace.NamespaceContext;
040:
041: import org.xml.sax.Attributes;
042: import org.xml.sax.SAXException;
043:
044: /**
045: * {@link XmlVisitor} decorator that interns all string tokens.
046: *
047: * @author Kohsuke Kawaguchi
048: */
049: public final class InterningXmlVisitor implements XmlVisitor {
050: private final XmlVisitor next;
051:
052: private final AttributesImpl attributes = new AttributesImpl();
053:
054: public InterningXmlVisitor(XmlVisitor next) {
055: this .next = next;
056: }
057:
058: public void startDocument(LocatorEx locator,
059: NamespaceContext nsContext) throws SAXException {
060: next.startDocument(locator, nsContext);
061: }
062:
063: public void endDocument() throws SAXException {
064: next.endDocument();
065: }
066:
067: public void startElement(TagName tagName) throws SAXException {
068: attributes.setAttributes(tagName.atts);
069: tagName.atts = attributes;
070: tagName.uri = intern(tagName.uri);
071: tagName.local = intern(tagName.local);
072: next.startElement(tagName);
073: }
074:
075: public void endElement(TagName tagName) throws SAXException {
076: tagName.uri = intern(tagName.uri);
077: tagName.local = intern(tagName.local);
078: next.endElement(tagName);
079: }
080:
081: public void startPrefixMapping(String prefix, String nsUri)
082: throws SAXException {
083: next.startPrefixMapping(intern(prefix), intern(nsUri));
084: }
085:
086: public void endPrefixMapping(String prefix) throws SAXException {
087: next.endPrefixMapping(intern(prefix));
088: }
089:
090: public void text(CharSequence pcdata) throws SAXException {
091: next.text(pcdata);
092: }
093:
094: public UnmarshallingContext getContext() {
095: return next.getContext();
096: }
097:
098: public TextPredictor getPredictor() {
099: return next.getPredictor();
100: }
101:
102: private static class AttributesImpl implements Attributes {
103: private Attributes core;
104:
105: void setAttributes(Attributes att) {
106: this .core = att;
107: }
108:
109: public int getIndex(String qName) {
110: return core.getIndex(qName);
111: }
112:
113: public int getIndex(String uri, String localName) {
114: return core.getIndex(uri, localName);
115: }
116:
117: public int getLength() {
118: return core.getLength();
119: }
120:
121: public String getLocalName(int index) {
122: return intern(core.getLocalName(index));
123: }
124:
125: public String getQName(int index) {
126: return intern(core.getQName(index));
127: }
128:
129: public String getType(int index) {
130: return intern(core.getType(index));
131: }
132:
133: public String getType(String qName) {
134: return intern(core.getType(qName));
135: }
136:
137: public String getType(String uri, String localName) {
138: return intern(core.getType(uri, localName));
139: }
140:
141: public String getURI(int index) {
142: return intern(core.getURI(index));
143: }
144:
145: //
146: // since values may vary a lot,
147: // we don't (probably shouldn't) intern values.
148: //
149:
150: public String getValue(int index) {
151: return core.getValue(index);
152: }
153:
154: public String getValue(String qName) {
155: return core.getValue(qName);
156: }
157:
158: public String getValue(String uri, String localName) {
159: return core.getValue(uri, localName);
160: }
161: }
162:
163: private static String intern(String s) {
164: if (s == null)
165: return null;
166: else
167: return s.intern();
168: }
169: }
|