001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: package org.apache.xerces.dom;
019:
020: import java.util.StringTokenizer;
021: import java.util.Vector;
022: import org.w3c.dom.DOMImplementationList;
023: import org.w3c.dom.DOMImplementationSource;
024: import org.w3c.dom.DOMImplementation;
025: import org.apache.xerces.dom.DOMImplementationListImpl;
026:
027: /**
028: * Supply one the right implementation, based upon requested features. Each
029: * implemented <code>DOMImplementationSource</code> object is listed in the
030: * binding-specific list of available sources so that its
031: * <code>DOMImplementation</code> objects are made available.
032: *
033: * <p>See also the <a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#DOMImplementationSource'>Document Object Model (DOM) Level 3 Core Specification</a>.
034: *
035: * @xerces.internal
036: *
037: * @version $Id: DOMImplementationSourceImpl.java 447266 2006-09-18 05:57:49Z mrglavas $
038: */
039: public class DOMImplementationSourceImpl implements
040: DOMImplementationSource {
041:
042: /**
043: * A method to request a DOM implementation.
044: * @param features A string that specifies which features are required.
045: * This is a space separated list in which each feature is specified
046: * by its name optionally followed by a space and a version number.
047: * This is something like: "XML 1.0 Traversal Events 2.0"
048: * @return An implementation that has the desired features, or
049: * <code>null</code> if this source has none.
050: */
051: public DOMImplementation getDOMImplementation(String features) {
052: // first check whether the CoreDOMImplementation would do
053: DOMImplementation impl = CoreDOMImplementationImpl
054: .getDOMImplementation();
055: if (testImpl(impl, features)) {
056: return impl;
057: }
058: // if not try the DOMImplementation
059: impl = DOMImplementationImpl.getDOMImplementation();
060: if (testImpl(impl, features)) {
061: return impl;
062: }
063:
064: return null;
065: }
066:
067: /**
068: * A method to request a list of DOM implementations that support the
069: * specified features and versions, as specified in .
070: * @param features A string that specifies which features and versions
071: * are required. This is a space separated list in which each feature
072: * is specified by its name optionally followed by a space and a
073: * version number. This is something like: "XML 3.0 Traversal +Events
074: * 2.0"
075: * @return A list of DOM implementations that support the desired
076: * features.
077: */
078: public DOMImplementationList getDOMImplementationList(
079: String features) {
080: // first check whether the CoreDOMImplementation would do
081: DOMImplementation impl = CoreDOMImplementationImpl
082: .getDOMImplementation();
083: final Vector implementations = new Vector();
084: if (testImpl(impl, features)) {
085: implementations.addElement(impl);
086: }
087: impl = DOMImplementationImpl.getDOMImplementation();
088: if (testImpl(impl, features)) {
089: implementations.addElement(impl);
090: }
091:
092: return new DOMImplementationListImpl(implementations);
093: }
094:
095: boolean testImpl(DOMImplementation impl, String features) {
096:
097: StringTokenizer st = new StringTokenizer(features);
098: String feature = null;
099: String version = null;
100:
101: if (st.hasMoreTokens()) {
102: feature = st.nextToken();
103: }
104: while (feature != null) {
105: boolean isVersion = false;
106: if (st.hasMoreTokens()) {
107: char c;
108: version = st.nextToken();
109: c = version.charAt(0);
110: switch (c) {
111: case '0':
112: case '1':
113: case '2':
114: case '3':
115: case '4':
116: case '5':
117: case '6':
118: case '7':
119: case '8':
120: case '9':
121: isVersion = true;
122: }
123: } else {
124: version = null;
125: }
126: if (isVersion) {
127: if (!impl.hasFeature(feature, version)) {
128: return false;
129: }
130: if (st.hasMoreTokens()) {
131: feature = st.nextToken();
132: } else {
133: feature = null;
134: }
135: } else {
136: if (!impl.hasFeature(feature, null)) {
137: return false;
138: }
139: feature = version;
140: }
141: }
142: return true;
143: }
144: }
|