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
NodeSortRecordFactory(DOM dom, String className, Translet translet, String order[], String type[])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      */
NodeSortRecordFactory(DOM dom, String className, Translet translet, String order[], String type[], String lang[], String caseOrder[])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      */
makeNodeSortRecord(int node, int last)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 
getClassName()168     public String getClassName() {
169         return _className;
170     }
171 
setLang(final String lang[])172    private final void setLang(final String lang[]){
173 
174     }
175 }
176