1 /* 2 * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. 3 */ 4 /* 5 * Licensed to the Apache Software Foundation (ASF) under one or more 6 * contributor license agreements. See the NOTICE file distributed with 7 * this work for additional information regarding copyright ownership. 8 * The ASF licenses this file to You under the Apache License, Version 2.0 9 * (the "License"); you may not use this file except in compliance with 10 * the License. You may obtain a copy of the License at 11 * 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 14 * Unless required by applicable law or agreed to in writing, software 15 * distributed under the License is distributed on an "AS IS" BASIS, 16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 * See the License for the specific language governing permissions and 18 * limitations under the License. 19 */ 20 21 package com.sun.org.apache.xerces.internal.dom; 22 23 import java.util.ArrayList; 24 import java.util.List; 25 import java.util.StringTokenizer; 26 import org.w3c.dom.DOMImplementation; 27 import org.w3c.dom.DOMImplementationList; 28 import org.w3c.dom.DOMImplementationSource; 29 30 /** 31 * Supply one the right implementation, based upon requested features. Each 32 * implemented <code>DOMImplementationSource</code> object is listed in the 33 * binding-specific list of available sources so that its 34 * <code>DOMImplementation</code> objects are made available. 35 * 36 * <p>See also the 37 * <a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#DOMImplementationSource'> 38 * Document Object Model (DOM) Level 3 Core Specification</a>. 39 * 40 * @xerces.internal 41 * 42 * @LastModified: Oct 2017 43 */ 44 public class DOMImplementationSourceImpl 45 implements DOMImplementationSource { 46 47 /** 48 * A method to request a DOM implementation. 49 * @param features A string that specifies which features are required. 50 * This is a space separated list in which each feature is specified 51 * by its name optionally followed by a space and a version number. 52 * This is something like: "XML 1.0 Traversal Events 2.0" 53 * @return An implementation that has the desired features, or 54 * <code>null</code> if this source has none. 55 */ getDOMImplementation(String features)56 public DOMImplementation getDOMImplementation(String features) { 57 // first check whether the CoreDOMImplementation would do 58 DOMImplementation impl = 59 CoreDOMImplementationImpl.getDOMImplementation(); 60 if (testImpl(impl, features)) { 61 return impl; 62 } 63 // if not try the DOMImplementation 64 impl = DOMImplementationImpl.getDOMImplementation(); 65 if (testImpl(impl, features)) { 66 return impl; 67 } 68 69 return null; 70 } 71 72 /** 73 * A method to request a list of DOM implementations that support the 74 * specified features and versions, as specified in . 75 * @param features A string that specifies which features and versions 76 * are required. This is a space separated list in which each feature 77 * is specified by its name optionally followed by a space and a 78 * version number. This is something like: "XML 3.0 Traversal +Events 79 * 2.0" 80 * @return A list of DOM implementations that support the desired 81 * features. 82 */ getDOMImplementationList(String features)83 public DOMImplementationList getDOMImplementationList(String features) { 84 // first check whether the CoreDOMImplementation would do 85 DOMImplementation impl = CoreDOMImplementationImpl.getDOMImplementation(); 86 final List<DOMImplementation> implementations = new ArrayList<>(); 87 if (testImpl(impl, features)) { 88 implementations.add(impl); 89 } 90 impl = DOMImplementationImpl.getDOMImplementation(); 91 if (testImpl(impl, features)) { 92 implementations.add(impl); 93 } 94 95 return new DOMImplementationListImpl(implementations); 96 } 97 testImpl(DOMImplementation impl, String features)98 boolean testImpl(DOMImplementation impl, String features) { 99 100 StringTokenizer st = new StringTokenizer(features); 101 String feature = null; 102 String version = null; 103 104 if (st.hasMoreTokens()) { 105 feature = st.nextToken(); 106 } 107 while (feature != null) { 108 boolean isVersion = false; 109 if (st.hasMoreTokens()) { 110 char c; 111 version = st.nextToken(); 112 c = version.charAt(0); 113 switch (c) { 114 case '0': case '1': case '2': case '3': case '4': 115 case '5': case '6': case '7': case '8': case '9': 116 isVersion = true; 117 } 118 } else { 119 version = null; 120 } 121 if (isVersion) { 122 if (!impl.hasFeature(feature, version)) { 123 return false; 124 } 125 if (st.hasMoreTokens()) { 126 feature = st.nextToken(); 127 } else { 128 feature = null; 129 } 130 } else { 131 if (!impl.hasFeature(feature, null)) { 132 return false; 133 } 134 feature = version; 135 } 136 } 137 return true; 138 } 139 } 140