001: /*
002: * The contents of this file are subject to the terms
003: * of the Common Development and Distribution License
004: * (the License). You may not use this file except in
005: * compliance with the License.
006: *
007: * You can obtain a copy of the license at
008: * https://glassfish.dev.java.net/public/CDDLv1.0.html.
009: * See the License for the specific language governing
010: * permissions and limitations under the License.
011: *
012: * When distributing Covered Code, include this CDDL
013: * Header Notice in each file and include the License file
014: * at https://glassfish.dev.java.net/public/CDDLv1.0.html.
015: * If applicable, add the following below the CDDL Header,
016: * with the fields enclosed by brackets [] replaced by
017: * you own identifying information:
018: * "Portions Copyrighted [year] [name of copyright owner]"
019: *
020: * Copyright 2006 Sun Microsystems Inc. All Rights Reserved
021: */
022:
023: /*
024: * BaseCanonicalizer.java
025: *
026: * Created on August 20, 2005, 5:26 PM
027: *
028: * To change this template, choose Tools | Options and locate the template under
029: * the Source Creation and Management node. Right-click the template and choose
030: * Open. You can then make changes to the template in the Source Editor.
031: */
032:
033: /*
034: * Copyright 1999-2004 The Apache Software Foundation.
035: *
036: * Licensed under the Apache License, Version 2.0 (the "License");
037: * you may not use this file except in compliance with the License.
038: * You may obtain a copy of the License at
039: *
040: * http://www.apache.org/licenses/LICENSE-2.0
041: *
042: * Unless required by applicable law or agreed to in writing, software
043: * distributed under the License is distributed on an "AS IS" BASIS,
044: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
045: * See the License for the specific language governing permissions and
046: * limitations under the License.
047: *
048: */
049:
050: package com.sun.xml.wss.impl.c14n;
051:
052: import com.sun.xml.wss.impl.misc.UnsyncByteArrayOutputStream;
053: import java.io.IOException;
054: import java.io.OutputStream;
055: import java.util.ArrayList;
056: import java.util.Arrays;
057: import java.util.HashMap;
058: import java.util.Iterator;
059: import java.util.List;
060: import java.util.Set;
061: import java.util.Stack;
062: import javax.xml.XMLConstants;
063: import org.xml.sax.Attributes;
064:
065: /**
066: *
067: * @author Apache
068: * @author K.Venugopal@sun.com
069: * //TODO:
070: * Refactor code ..
071: */
072: public abstract class BaseCanonicalizer {
073: //extends DefaultHandler2 {
074: static final byte[] _END_PI = { '?', '>' };
075: static final byte[] _BEGIN_PI = { '<', '?' };
076: static final byte[] _END_COMM = { '-', '-', '>' };
077: static final byte[] _BEGIN_COMM = { '<', '!', '-', '-' };
078: static final byte[] __XA_ = { '&', '#', 'x', 'A', ';' };
079: static final byte[] __X9_ = { '&', '#', 'x', '9', ';' };
080: static final byte[] _QUOT_ = { '&', 'q', 'u', 'o', 't', ';' };
081: static final byte[] __XD_ = { '&', '#', 'x', 'D', ';' };
082: static final byte[] _GT_ = { '&', 'g', 't', ';' };
083: static final byte[] _LT_ = { '&', 'l', 't', ';' };
084: static final byte[] _END_TAG = { '<', '/' };
085: static final byte[] _AMP_ = { '&', 'a', 'm', 'p', ';' };
086: final static String XML = "xml";
087: final static String XMLNS = "xmlns";
088: final static byte[] equalsStr = { '=', '\"' };
089: static final int NODE_BEFORE_DOCUMENT_ELEMENT = -1;
090: static final int NODE_NOT_BEFORE_OR_AFTER_DOCUMENT_ELEMENT = 0;
091: static final int NODE_AFTER_DOCUMENT_ELEMENT = 1;
092: protected ArrayList _attrs = new ArrayList();
093: protected ArrayList _nsAttrs = new ArrayList();
094: int _attrPos = 0;
095: int _attrNSPos = 0;
096: protected List _attrResult = null;
097: //protected SortedSet _nsResult = new TreeSet(new AttrSorter(true));
098: protected List _nsResult = new ArrayList();
099: String _defURI = null;
100: OutputStream _stream = null;
101: boolean[] _ncContextState = new boolean[20];
102: StringBuffer _attrName = new StringBuffer();
103: int _depth = 0;
104: protected static final int initalCacheSize = 4;
105: boolean _parentNamespacesAdded = false;
106: //List _parentNamespaces = null;
107: String _elementPrefix = "";
108: private static boolean debug = false;
109:
110: /** Creates a new instance of BaseCanonicalizer */
111: public BaseCanonicalizer() {
112: }
113:
114: public void reset() {
115: _nsResult.clear();
116: _attrResult.clear();
117: _attrPos = 0;
118: _depth = 0;
119: _parentNamespacesAdded = false;
120:
121: }
122:
123: public void setStream(OutputStream os) {
124: this ._stream = os;
125: }
126:
127: public OutputStream getOutputStream() {
128: return this ._stream;
129: }
130:
131: protected final void resize() {
132: if (_depth >= _ncContextState.length) {
133: boolean[] tmp = new boolean[_ncContextState.length + 20];
134: System.arraycopy(_ncContextState, 0, tmp, 0,
135: _ncContextState.length);
136: _ncContextState = tmp;
137: }
138: }
139:
140: public void addParentNamespaces(List nsDecls) {
141: if (!_parentNamespacesAdded) {
142: //_parentNamespaces = nsDecls;
143: _nsResult.addAll(nsDecls);
144: _parentNamespacesAdded = true;
145: }
146: }
147:
148: protected AttributeNS getAttributeNS() {
149: if (_attrNSPos < _nsAttrs.size()) {
150: return (AttributeNS) _nsAttrs.get(_attrNSPos++);
151: } else {
152: for (int i = 0; i < initalCacheSize; i++) {
153: _nsAttrs.add(new AttributeNS());
154: }
155: return (AttributeNS) _nsAttrs.get(_attrNSPos++);
156: }
157: }
158:
159: protected void writeAttributes(Attributes attributes, Iterator itr)
160: throws IOException {
161: while (itr.hasNext()) {
162: Attribute attr = (Attribute) itr.next();
163: int pos = attr.getPosition();
164:
165: outputAttrToWriter(attributes.getQName(pos), attributes
166: .getValue(pos), _stream);
167: }
168: _attrResult.iterator();
169: }
170:
171: protected void writeAttributesNS(Iterator itr) throws IOException {
172: while (itr.hasNext()) {
173: AttributeNS attr = (AttributeNS) itr.next();
174: String prefix = attr.getPrefix();
175: if (prefix.length() != 0) {
176: _attrName.setLength(0);
177: _attrName.append("xmlns:");
178: _attrName.append(prefix);
179: prefix = _attrName.toString();
180: } else {
181: prefix = "xmlns";
182: }
183:
184: outputAttrToWriter(prefix, attr.getUri(), _stream);
185: }
186: }
187:
188: void outputTextToWriter(char[] text, int start, int length,
189: final OutputStream writer) throws IOException {
190:
191: byte[] toWrite = null;
192: for (int i = start; i < start + length; i++) {
193: char c = text[i];
194:
195: switch (c) {
196:
197: case '&':
198: if (Arrays.equals(toWrite, __XD_))
199: writer.write(toWrite);
200: toWrite = _AMP_;
201: //writer.write(_AMP_);
202: break;
203:
204: case '<':
205: if (Arrays.equals(toWrite, __XD_))
206: writer.write(toWrite);
207: toWrite = _LT_;
208: //writer.write(_LT_);
209: break;
210:
211: case '>':
212: if (Arrays.equals(toWrite, __XD_))
213: writer.write(toWrite);
214: toWrite = _GT_;
215: //writer.write(_GT_);
216: break;
217:
218: case 0xD:
219: if (Arrays.equals(toWrite, __XD_))
220: writer.write(toWrite);
221: toWrite = __XD_;
222: //writer.write(__XD_);
223: break;
224:
225: case 0xA:
226: toWrite = null;
227: writeCharToUtf8(c, writer);
228: break;
229:
230: default:
231: if (Arrays.equals(toWrite, __XD_)) {
232: writer.write(toWrite);
233: toWrite = null;
234: }
235: writeCharToUtf8(c, writer);
236: continue;
237: }
238: if (toWrite != null && !Arrays.equals(toWrite, __XD_))
239: writer.write(toWrite);
240: }
241: }
242:
243: final static void outputAttrToWriter(final String name,
244: final String value, final OutputStream writer)
245: throws IOException {
246: writer.write(' ');
247: writeStringToUtf8(name, writer);
248: writer.write(equalsStr);
249: byte[] toWrite;
250: final int length = value.length();
251: for (int i = 0; i < length; i++) {
252: char c = value.charAt(i);
253:
254: switch (c) {
255:
256: case '&':
257: toWrite = _AMP_;
258: //writer.write(_AMP_);
259: break;
260:
261: case '<':
262: toWrite = _LT_;
263: //writer.write(_LT_);
264: break;
265:
266: case '"':
267: toWrite = _QUOT_;
268: //writer.write(_QUOT_);
269: break;
270:
271: case 0x09: // '\t'
272: toWrite = __X9_;
273: //writer.write(__X9_);
274: break;
275:
276: case 0x0A: // '\n'
277: toWrite = __XA_;
278: //writer.write(__XA_);
279: break;
280:
281: case 0x0D: // '\r'
282: toWrite = __XD_;
283: //writer.write(__XD_);
284: break;
285:
286: default:
287: writeCharToUtf8(c, writer);
288: //this._writer.write(c);
289: continue;
290: }
291: writer.write(toWrite);
292: }
293:
294: writer.write('\"');
295: }
296:
297: final static void outputAttrToWriter(String prefix,
298: final String localName, final String value,
299: final OutputStream writer) throws IOException {
300: writer.write(' ');
301: if (localName.length() != 0) {
302: writeStringToUtf8(prefix, writer);
303: writeStringToUtf8(":", writer);
304: writeStringToUtf8(localName, writer);
305: } else {
306: writeStringToUtf8(prefix, writer);
307: }
308:
309: writer.write(equalsStr);
310: byte[] toWrite;
311: final int length = value.length();
312: for (int i = 0; i < length; i++) {
313: char c = value.charAt(i);
314:
315: switch (c) {
316:
317: case '&':
318: toWrite = _AMP_;
319: //writer.write(_AMP_);
320: break;
321:
322: case '<':
323: toWrite = _LT_;
324: //writer.write(_LT_);
325: break;
326:
327: case '"':
328: toWrite = _QUOT_;
329: //writer.write(_QUOT_);
330: break;
331:
332: case 0x09: // '\t'
333: toWrite = __X9_;
334: //writer.write(__X9_);
335: break;
336:
337: case 0x0A: // '\n'
338: toWrite = __XA_;
339: //writer.write(__XA_);
340: break;
341:
342: case 0x0D: // '\r'
343: toWrite = __XD_;
344: //writer.write(__XD_);
345: break;
346:
347: default:
348: writeCharToUtf8(c, writer);
349: //this._writer.write(c);
350: continue;
351: }
352: writer.write(toWrite);
353: }
354:
355: writer.write('\"');
356: }
357:
358: final static void writeCharToUtf8(final char c,
359: final OutputStream out) throws IOException {
360: char ch;
361: if (/*(c >= 0x0001) &&*/(c <= 0x007F)) {
362: out.write(c);
363: return;
364: }
365: int bias;
366: int write;
367: if (c > 0x07FF) {
368: ch = (char) (c >>> 12);
369: write = 0xE0;
370: if (ch > 0) {
371: write |= (ch & 0x0F);
372: }
373: out.write(write);
374: write = 0x80;
375: bias = 0x3F;
376: } else {
377: write = 0xC0;
378: bias = 0x1F;
379: }
380: ch = (char) (c >>> 6);
381: if (ch > 0) {
382: write |= (ch & bias);
383: }
384: out.write(write);
385: out.write(0x80 | ((c) & 0x3F));
386:
387: }
388:
389: final static void writeStringToUtf8(final String str,
390: final OutputStream out) throws IOException {
391: final int length = str.length();
392: int i = 0;
393: char c;
394: while (i < length) {
395: c = str.charAt(i++);
396: if (/*(c >= 0x0001) &&*/(c <= 0x007F)) {
397: out.write(c);
398: continue;
399: }
400: char ch;
401: int bias;
402: int write;
403: if (c > 0x07FF) {
404: ch = (char) (c >>> 12);
405: write = 0xE0;
406: if (ch > 0) {
407: write |= (ch & 0x0F);
408: }
409: out.write(write);
410: write = 0x80;
411: bias = 0x3F;
412: } else {
413: write = 0xC0;
414: bias = 0x1F;
415: }
416: ch = (char) (c >>> 6);
417: if (ch > 0) {
418: write |= (ch & bias);
419: }
420: out.write(write);
421: out.write(0x80 | ((c) & 0x3F));
422: continue;
423:
424: }
425:
426: }
427:
428: /**
429: * Outputs a PI to the internal Writer.
430: *
431: * @param currentPI
432: * @param writer where to write the things
433: * @throws IOException
434: */
435:
436: static final void outputPItoWriter(String target, String data,
437: OutputStream writer) throws IOException {
438:
439: //Assume comments after document element only.
440: //as this will be used to canonicalize body.
441:
442: writer.write('\n');
443:
444: writer.write(_BEGIN_PI);
445:
446: int length = target.length();
447:
448: for (int i = 0; i < length; i++) {
449: char c = target.charAt(i);
450: if (c == 0x0D) {
451: writer.write(__XD_);
452: } else {
453: writeCharToUtf8(c, writer);
454: }
455: }
456:
457: length = data.length();
458:
459: if (length > 0) {
460: writer.write(' ');
461:
462: for (int i = 0; i < length; i++) {
463: char c = data.charAt(i);
464: if (c == 0x0D) {
465: writer.write(__XD_);
466: } else {
467: writeCharToUtf8(c, writer);
468: }
469: }
470: }
471:
472: writer.write(_END_PI);
473:
474: }
475:
476: /**
477: * Method outputCommentToWriter
478: *
479: * @param currentComment
480: * @param writer writer where to write the things
481: * @throws IOException
482: */
483:
484: static final void outputCommentToWriter(String data,
485: OutputStream writer) throws IOException {
486: //Assume comments after document element only.
487: //as this will be used to canonicalize body.
488:
489: writer.write('\n');
490:
491: writer.write(_BEGIN_COMM);
492:
493: final int length = data.length();
494:
495: for (int i = 0; i < length; i++) {
496: char c = data.charAt(i);
497: if (c == 0x0D) {
498: writer.write(__XD_);
499: } else {
500: writeCharToUtf8(c, writer);
501: }
502: }
503:
504: writer.write(_END_COMM);
505:
506: }
507:
508: void outputTextToWriter(String text, OutputStream writer)
509: throws IOException {
510: byte[] toWrite = null;
511: for (int i = 0; i < text.length(); i++) {
512: char c = text.charAt(i);
513:
514: switch (c) {
515:
516: case '&':
517: if (Arrays.equals(toWrite, __XD_))
518: writer.write(toWrite);
519: toWrite = _AMP_;
520: //writer.write(_AMP_);
521: break;
522:
523: case '<':
524: if (Arrays.equals(toWrite, __XD_))
525: writer.write(toWrite);
526: toWrite = _LT_;
527: //writer.write(_LT_);
528: break;
529:
530: case '>':
531: if (Arrays.equals(toWrite, __XD_))
532: writer.write(toWrite);
533: toWrite = _GT_;
534: //writer.write(_GT_);
535: break;
536:
537: case 0xD:
538: if (Arrays.equals(toWrite, __XD_))
539: writer.write(toWrite);
540: toWrite = __XD_;
541: //writer.write(__XD_);
542: break;
543:
544: case 0xA:
545: toWrite = null;
546: writeCharToUtf8(c, writer);
547: break;
548:
549: default:
550: if (Arrays.equals(toWrite, __XD_)) {
551: writer.write(toWrite);
552: toWrite = null;
553: }
554: writeCharToUtf8(c, writer);
555: continue;
556: }
557: if (toWrite != null && !Arrays.equals(toWrite, __XD_))
558: writer.write(toWrite);
559: }
560: }
561:
562: /**
563: * Method namespaceIsRelative
564: *
565: * @param namespaceValue
566: * @return true if the given namespace is relative.
567: */
568: public static boolean namespaceIsRelative(String namespaceValue) {
569: return !namespaceIsAbsolute(namespaceValue);
570: }
571:
572: /**
573: * Method namespaceIsAbsolute
574: *
575: * @param namespaceValue
576: * @return true if the given namespace is absolute.
577: */
578: public static boolean namespaceIsAbsolute(String namespaceValue) {
579:
580: // assume empty namespaces are absolute
581: if (namespaceValue.length() == 0) {
582: return true;
583: }
584: return namespaceValue.indexOf(':') > 0;
585: }
586:
587: /*
588: *
589: * NamespaceContext implementation.
590: *
591: */
592: public static class NamespaceContextImpl implements
593: javax.xml.namespace.NamespaceContext {
594:
595: AttributeNS nsDecl = new AttributeNS();
596: HashMap prefixMappings = new HashMap();
597: ArrayList clearDepth = new ArrayList(10);
598:
599: int nsDepth;
600: int resizeBy = 10;
601:
602: public NamespaceContextImpl() {
603: //change this
604: for (int i = 0; i < 10; i++) {
605: clearDepth.add(null);
606: }
607:
608: }
609:
610: public AttributeNS getNamespaceDeclaration(String prefix) {
611: Stack stack = (Stack) prefixMappings.get(prefix);
612: if (stack == null || stack.empty()) {
613: return null;
614: }
615: AttributeNS attrNS = (AttributeNS) stack.peek();
616: if (attrNS.isWritten()) {
617: if (debug) {
618: System.out.println("depth " + nsDepth
619: + " did not return prefix " + prefix);
620: }
621: return null;
622: }
623: UsedNSList uList = null;
624:
625: uList = (UsedNSList) clearDepth.get(nsDepth);
626: if (uList == null) {
627: uList = new UsedNSList();
628: clearDepth.set(nsDepth, uList);
629: }
630: if (debug) {
631: System.out.println("depth " + nsDepth
632: + " return prefix " + prefix);
633: }
634: uList.getUsedPrefixList().add(prefix);
635: return attrNS;
636: }
637:
638: public void declareNamespace(String prefix, String uri) {
639: Stack nsDecls = (Stack) prefixMappings.get(prefix);
640: nsDecl.setPrefix(prefix);
641: nsDecl.setUri(uri);
642: if (nsDecls == null) {
643: nsDecls = new Stack();
644: try {
645: nsDecls.add(nsDecl.clone());
646: prefixMappings.put(prefix, nsDecls);
647: } catch (CloneNotSupportedException ex) {
648: throw new RuntimeException(ex);
649: }
650: } else if (!nsDecls.contains(nsDecl)) {
651: try {
652: nsDecls.add(nsDecl.clone());
653: } catch (CloneNotSupportedException ex) {
654: throw new RuntimeException(ex);
655: }
656: } else {
657: return;
658: }
659:
660: UsedNSList uList = null;
661: uList = (UsedNSList) clearDepth.get(nsDepth);
662: if (uList == null) {
663: uList = new UsedNSList();
664: clearDepth.set(nsDepth, uList);
665: }
666: ArrayList prefixList = uList.getPopList();
667: prefixList.add(prefix);
668: }
669:
670: public void push() {
671: nsDepth++;
672: if (debug) {
673: System.out
674: .println("--------------------Push depth----------------"
675: + nsDepth);
676: }
677: if (nsDepth >= clearDepth.size()) {
678: clearDepth.ensureCapacity(clearDepth.size() + resizeBy);
679: int len = clearDepth.size();
680: for (int i = len; i < len + resizeBy; i++) {
681: clearDepth.add(null);
682: }
683: }
684: }
685:
686: public void pop() {
687: if (nsDepth <= 0) {
688: return;
689: }
690: UsedNSList ul = (UsedNSList) clearDepth.get(nsDepth);
691: if (debug) {
692: System.out
693: .println("---------------------pop depth----------------------"
694: + nsDepth);
695: }
696: nsDepth--;
697: if (ul == null) {
698: return;
699: }
700: ArrayList pList = ul.getPopList();
701: for (int i = 0; i < pList.size(); i++) {
702: String prefix = (String) pList.get(i);
703: Stack stack = (Stack) prefixMappings.get(prefix);
704: if (debug) {
705: System.out.println("clear prefix" + prefix);
706: }
707: if (!stack.isEmpty()) {
708: stack.pop();
709: }
710: }
711:
712: ArrayList rList = ul.getUsedPrefixList();
713: for (int i = 0; i < rList.size(); i++) {
714: String prefix = (String) rList.get(i);
715: if (pList.contains(prefix)) {
716: continue;
717: }
718: Stack stack = (Stack) prefixMappings.get(prefix);
719: if (debug) {
720: System.out.println("reset written prefix" + prefix);
721: }
722: if (!stack.isEmpty()) {
723: AttributeNS attrNS = (AttributeNS) stack.peek();
724: attrNS.setWritten(false);
725: }
726: }
727: pList.clear();
728: rList.clear();
729: }
730:
731: public void reset() {
732: nsDepth = 0;
733: for (int i = 0; i < clearDepth.size(); i++) {
734: UsedNSList ul = (UsedNSList) clearDepth.get(i);
735: if (ul == null) {
736: continue;
737: }
738: ul.clear();
739: }
740: }
741:
742: public String getNamespaceURI(String prefix) {
743: Stack stack = (Stack) prefixMappings.get(prefix);
744: if (stack == null || stack.empty()) {
745: return XMLConstants.NULL_NS_URI;
746: }
747: AttributeNS attrNS = (AttributeNS) stack.peek();
748: return attrNS.getUri();
749: }
750:
751: public String getPrefix(String namespaceURI) {
752: Set<String> keys = prefixMappings.keySet();
753:
754: Iterator<String> itr = keys.iterator();
755: while (itr.hasNext()) {
756: String key = itr.next();
757: Stack stack = (Stack) prefixMappings.get(key);
758: if (stack == null || stack.empty()) {
759: continue;
760: }
761: AttributeNS attrNS = (AttributeNS) stack.peek();
762: if (namespaceURI.equals(attrNS.getUri())) {
763: return key;
764: }
765: }
766: return null;
767: }
768:
769: public Iterator getPrefixes(String namespaceURI) {
770: Set<String> keys = prefixMappings.keySet();
771: ArrayList list = new ArrayList();
772: Iterator<String> itr = keys.iterator();
773: while (itr.hasNext()) {
774: String key = itr.next();
775: Stack stack = (Stack) prefixMappings.get(key);
776: if (stack == null || stack.empty()) {
777: continue;
778: }
779: AttributeNS attrNS = (AttributeNS) stack.peek();
780: if (namespaceURI.equals(attrNS.getUri())) {
781: list.add(key);
782: }
783: }
784:
785: return list.iterator();
786:
787: }
788: }
789:
790: static class UsedNSList {
791: ArrayList usedPrefixList = new ArrayList();
792: ArrayList popPrefixList = new ArrayList();
793:
794: public ArrayList getPopList() {
795: return popPrefixList;
796: }
797:
798: public ArrayList getUsedPrefixList() {
799: return usedPrefixList;
800: }
801:
802: public void clear() {
803: usedPrefixList.clear();
804: popPrefixList.clear();
805: }
806: }
807:
808: static class ElementName {
809: //byte [] utf8Data = new UnsyncBufferedOutputStream(20);
810: private UnsyncByteArrayOutputStream utf8Data = new UnsyncByteArrayOutputStream(
811: 20);
812:
813: public UnsyncByteArrayOutputStream getUtf8Data() {
814: return utf8Data;
815: }
816:
817: public void setUtf8Data(UnsyncByteArrayOutputStream utf8Data) {
818: this .utf8Data = utf8Data;
819: }
820: }
821:
822: /*public static void sort(List list) {
823: Object[] a = list.toArray();
824: int size = a.length;
825: for ( int iterator=0; iterator<size; iterator++) {
826: for ( int iterator1=iterator+1; iterator1<size; iterator1++) {
827: if ( ((Comparable)a[iterator1]).compareTo(a[iterator])<=0 ) {
828: swap(a, iterator1, iterator);
829: }
830: }
831: }
832: //ListIterator<T> i = list.listIterator();
833: ListIterator i = list.listIterator();
834: for (int j=0; j<a.length; j++) {
835: i.next();
836: //i.set((T)a[j]);
837: i.set(a[j]);
838: }
839: }*/
840:
841: public static void sort(List list) {
842: int size = list.size();
843: for (int iterator = 0; iterator < size; iterator++) {
844: for (int iterator1 = iterator + 1; iterator1 < size; iterator1++) {
845: if (((Comparable) list.get(iterator1)).compareTo(list
846: .get(iterator)) >= 0) {
847: swap(list, iterator1, iterator);
848: }
849: }
850: }
851: }
852:
853: /*private static void swap(Object[] x, int a, int b) {
854: Object t = x[a];
855: x[a] = x[b];
856: x[b] = t;
857: }*/
858:
859: private static void swap(List x, int a, int b) {
860: Object t = x.get(a);
861: x.set(a, x.get(b));
862: x.set(b, t);
863: }
864:
865: }
|