1 /* 2 * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. 3 * @LastModified: Oct 2017 4 */ 5 /* 6 * Licensed to the Apache Software Foundation (ASF) under one or more 7 * contributor license agreements. See the NOTICE file distributed with 8 * this work for additional information regarding copyright ownership. 9 * The ASF licenses this file to You under the Apache License, Version 2.0 10 * (the "License"); you may not use this file except in compliance with 11 * the License. You may obtain a copy of the License at 12 * 13 * http://www.apache.org/licenses/LICENSE-2.0 14 * 15 * Unless required by applicable law or agreed to in writing, software 16 * distributed under the License is distributed on an "AS IS" BASIS, 17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 * See the License for the specific language governing permissions and 19 * limitations under the License. 20 */ 21 22 package com.sun.org.apache.xerces.internal.dom; 23 24 import java.util.ArrayList; 25 import java.util.List; 26 import java.util.StringTokenizer; 27 import org.w3c.dom.DOMImplementation; 28 import org.w3c.dom.DOMImplementationList; 29 import org.w3c.dom.DOMImplementationSource; 30 31 /** 32 * Supply one the right implementation, based upon requested features. Each 33 * implemented <code>DOMImplementationSource</code> object is listed in the 34 * binding-specific list of available sources so that its 35 * <code>DOMImplementation</code> objects are made available. 36 * 37 * <p>See also the 38 * <a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#DOMImplementationSource'> 39 * Document Object Model (DOM) Level 3 Core Specification</a>. 40 * 41 * @xerces.internal 42 * 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 */ 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 */ 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 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 }