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 21package com.sun.org.apache.xalan.internal.xsltc.dom; 22 23import com.sun.org.apache.xalan.internal.xsltc.DOM; 24import com.sun.org.apache.xalan.internal.xsltc.Translet; 25import com.sun.org.apache.xalan.internal.xsltc.TransletException; 26import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet; 27import com.sun.org.apache.xml.internal.utils.LocaleUtility; 28import com.sun.org.apache.xalan.internal.utils.ObjectFactory; 29import java.lang.reflect.InvocationTargetException; 30import java.util.Locale; 31import java.text.Collator; 32 33public class NodeSortRecordFactory { 34 35 private static int DESCENDING = "descending".length(); 36 private static int NUMBER = "number".length(); 37 38 private final DOM _dom; 39 private final String _className; 40 private Class _class; 41 private SortSettings _sortSettings; 42 43 /** 44 * 45 */ 46 protected Collator _collator; 47 48 /** 49 * Creates a NodeSortRecord producing object. The DOM specifies which tree 50 * to get the nodes to sort from, the class name specifies what auxillary 51 * class to use to sort the nodes (this class is generated by the Sort 52 * class), and the translet parameter is needed for methods called by 53 * this object. 54 * 55 * @deprecated This constructor is no longer used in generated code. It 56 * exists only for backwards compatibility. 57 */ 58 @Deprecated 59 public NodeSortRecordFactory(DOM dom, String className, Translet translet, 60 String order[], String type[]) 61 throws TransletException 62 { 63 this(dom, className, translet, order, type, null, null); 64 } 65 66 /** 67 * Creates a NodeSortRecord producing object. The DOM specifies which tree 68 * to get the nodes to sort from, the class name specifies what auxillary 69 * class to use to sort the nodes (this class is generated by the Sort 70 * class), and the translet parameter is needed for methods called by 71 * this object. 72 */ 73 public NodeSortRecordFactory(DOM dom, String className, Translet translet, 74 String order[], String type[], String lang[], 75 String caseOrder[]) 76 throws TransletException 77 { 78 try { 79 _dom = dom; 80 _className = className; 81 // This should return a Class definition if using TrAX 82 _class = translet.getAuxiliaryClass(className); 83 // This code is only run when the native API is used 84 if (_class == null) { 85 _class = ObjectFactory.findProviderClass(className, true); 86 } 87 88 int levels = order.length; 89 int[] iOrder = new int[levels]; 90 int[] iType = new int[levels]; 91 for (int i = 0; i < levels; i++) { 92 if (order[i].length() == DESCENDING) { 93 iOrder[i] = NodeSortRecord.COMPARE_DESCENDING; 94 } 95 if (type[i].length() == NUMBER) { 96 iType[i] = NodeSortRecord.COMPARE_NUMERIC; 97 } 98 } 99 100 // Old NodeSortRecordFactory constructor had no lang or case_order 101 // arguments. Provide default values in that case for binary 102 // compatibility. 103 String[] emptyStringArray = null; 104 if (lang == null || caseOrder == null) { 105 int numSortKeys = order.length; 106 emptyStringArray = new String[numSortKeys]; 107 108 // Set up array of zero-length strings as default values 109 // of lang and case_order 110 for (int i = 0; i < numSortKeys; i++) { 111 emptyStringArray[i] = ""; 112 } 113 } 114 115 if (lang == null) { 116 lang = emptyStringArray; 117 } 118 if (caseOrder == null) { 119 caseOrder = emptyStringArray; 120 } 121 122 final int length = lang.length; 123 Locale[] locales = new Locale[length]; 124 Collator[] collators = new Collator[length]; 125 for (int i = 0; i< length; i++){ 126 locales[i] = LocaleUtility.langToLocale(lang[i]); 127 collators[i] = Collator.getInstance(locales[i]); 128 } 129 130 _sortSettings = new SortSettings((AbstractTranslet) translet, 131 iOrder, iType, locales, collators, 132 caseOrder); 133 } catch (ClassNotFoundException e) { 134 throw new TransletException(e); 135 } 136 } 137 138 139 140 /** 141 * Create an instance of a sub-class of NodeSortRecord. The name of this 142 * sub-class is passed to us in the constructor. 143 */ 144 public NodeSortRecord makeNodeSortRecord(int node, int last) 145 throws ExceptionInInitializerError, 146 LinkageError, 147 IllegalAccessException, 148 InstantiationException, 149 SecurityException, 150 TransletException { 151 152 try { 153 final NodeSortRecord sortRecord; 154 //NodeSortRecord subclasses are generated with a public empty constructor 155 // refer to com.sun.org.apache.xalan.internal.xsltc.compiler.Sort::compileInit 156 sortRecord = (NodeSortRecord)_class.getConstructor().newInstance(); 157 sortRecord.initialize(node, last, _dom, _sortSettings); 158 return sortRecord; 159 } catch (NoSuchMethodException | IllegalArgumentException | 160 InvocationTargetException ex) { 161 throw new InstantiationException(ex.getMessage()); 162 } 163 } 164 165 public String getClassName() { 166 return _className; 167 } 168 169 private final void setLang(final String lang[]){ 170 171 } 172} 173