📄 arraydeserializer.java
字号:
* actual array after completion (by valueComplete). * It is important to wait until all indices have been * processed before invoking valueComplete. * @param value value of the array element * @param hint index of the array element (Integer) **/ public void setChildValue(Object value, Object hint) throws SAXException { if (log.isDebugEnabled()) { log.debug("Enter: ArrayDeserializer::setValue(" + value + ", " + hint + ")"); } ArrayList list = (ArrayList)this.value; int offset = ((Integer)hint).intValue(); if (this.mDimLength == null) { // Normal Case: Set the element in the list // grow the list if necessary to accomodate the new member while (list.size() <= offset) { list.add(null); } list.set(offset, value); } else { // Multi-Dim Array case: Need to find the nested ArrayList // and set the proper element. // Convert the offset into a series of indices ArrayList mDimIndex = toMultiIndex(offset); // Get/Create the nested ArrayList for(int i=0; i < mDimLength.size(); i++) { int length = ((Integer)mDimLength.get(i)).intValue(); int index = ((Integer)mDimIndex.get(i)).intValue(); while (list.size() < length) { list.add(null); } // If not the last dimension, get the nested ArrayList // Else set the value if (i < mDimLength.size()-1) { if (list.get(index) == null) { list.set(index, new ArrayList()); } list = (ArrayList) list.get(index); } else { list.set(index, value); } } } } /** * When valueComplete() is invoked on the array, * first convert the array value into the expected array. * Then call super.valueComplete() to inform referents * that the array value is ready. **/ public void valueComplete() throws SAXException { if (componentsReady()) { try { if (arrayClass != null) { value = JavaUtils.convert(value, arrayClass); } } catch (RuntimeException e) { // We must ignore exceptions from convert for Arrays with null - why? } } super.valueComplete(); } /** * Converts the given string to an index. * Assumes the string consists of a brackets surrounding comma * separated digits. For example "[2]" or [2,3]". * The routine returns a single index. * For example "[2]" returns 2. * For example "[2,3]" depends on the size of the multiple dimensions. * if the dimensions are "[3,5]" then 13 is returned (2*5) + 3. * @param text representing index text * @param exceptKey exception message key * @return index */ private int convertToIndex(String text, String exceptKey) throws SAXException { StringTokenizer tokenizer = new StringTokenizer(text, "[],"); int index = 0; try { if (mDimLength == null) { // Normal Case: Single dimension index = Integer.parseInt(tokenizer.nextToken()); if (tokenizer.hasMoreTokens()) { throw new SAXException( Messages.getMessage(exceptKey, text)); } } else { // Multiple Dimensions: int dim = -1; ArrayList work = new ArrayList(); while(tokenizer.hasMoreTokens()) { // Problem if the number of dimensions specified exceeds // the number of dimensions of arrayType dim++; if (dim >= mDimLength.size()) { throw new SAXException( Messages.getMessage(exceptKey, text)); } // Get the next token and convert to integer int workIndex = Integer.parseInt(tokenizer.nextToken()); // Problem if the index is out of range. if (workIndex < 0 || workIndex >= ((Integer)mDimLength.get(dim)).intValue()) { throw new SAXException( Messages.getMessage(exceptKey, text)); } work.add(new Integer(workIndex)); } index = toSingleIndex(work); // Convert to single index } } catch (SAXException e) { throw e; } catch (Exception e) { throw new SAXException(Messages.getMessage(exceptKey, text)); } return index; } /** * Converts single index to list of multiple indices. * @param single index * @return list of multiple indices or null if not multiple indices. */ private ArrayList toMultiIndex(int single) { if (mDimLength == null) return null; // Calculate the index factors if not already known if (mDimFactor == null) { mDimFactor = new ArrayList(); for (int i=0; i < mDimLength.size(); i++) { int factor = 1; for (int j=i+1; j<mDimLength.size(); j++) { factor *= ((Integer)mDimLength.get(j)).intValue(); } mDimFactor.add(new Integer(factor)); } } ArrayList rc = new ArrayList(); for (int i=0; i < mDimLength.size(); i++) { int factor = ((Integer)mDimFactor.get(i)).intValue(); rc.add(new Integer(single / factor)); single = single % factor; } return rc; } /** * Converts multiple index to single index. * @param indexArray list of multiple indices * @return single index */ private int toSingleIndex(ArrayList indexArray) { if (mDimLength == null || indexArray == null) return -1; // Calculate the index factors if not already known if (mDimFactor == null) { mDimFactor = new ArrayList(); for (int i=0; i < mDimLength.size(); i++) { int factor = 1; for (int j=i+1; j<mDimLength.size(); j++) { factor *= ((Integer)mDimLength.get(j)).intValue(); } mDimFactor.add(new Integer(factor)); } } int single = 0; for (int i=0; i < indexArray.size(); i++) { single += ((Integer)mDimFactor.get(i)).intValue()* ((Integer)indexArray.get(i)).intValue(); } return single; } /** * During processing, the Array Deserializer stores the array in * an ArrayListExtension class. This class contains all of the * normal function of an ArrayList, plus it keeps a list of the * converted array values. This class is essential to support * arrays that are multi-referenced. **/ public class ArrayListExtension extends ArrayList implements JavaUtils.ConvertCache { private HashMap table = null; private Class arrayClass = null; // The array class. /** * Constructors */ ArrayListExtension(Class arrayClass) { super(); this.arrayClass = arrayClass; // Don't use the array class as a hint // if it can't be instantiated if (arrayClass == null || arrayClass.isInterface() || java.lang.reflect.Modifier.isAbstract( arrayClass.getModifiers())) { arrayClass = null; } } ArrayListExtension(Class arrayClass, int length) { // Sanity check the array size, 50K is big enough to start super(length > 50000 ? 50000 : length); this.arrayClass = arrayClass; // Don't use the array class as a hint // if it can't be instantiated if (arrayClass == null || arrayClass.isInterface() || java.lang.reflect.Modifier.isAbstract( arrayClass.getModifiers())) { arrayClass = null; } } /** * Store converted value **/ public void setConvertedValue(Class cls, Object value) { if (table == null) table = new HashMap(); table.put(cls, value); } /** * Get previously converted value **/ public Object getConvertedValue(Class cls) { if (table == null) return null; return table.get(cls); } /** * Get the destination array class described by the xml **/ public Class getDestClass() { return arrayClass; } } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -