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 }