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