001/* 002// This software is subject to the terms of the Eclipse Public License v1.0 003// Agreement, available at the following URL: 004// http://www.eclipse.org/legal/epl-v10.html. 005// You must accept the terms of that agreement to use this software. 006// 007// Copyright (C) 2011-2011 Pentaho 008// All Rights Reserved. 009*/ 010package mondrian.util; 011 012import java.util.*; 013 014/** 015 * Composite collections. 016 * 017 * @author jhyde 018 */ 019public abstract class Composite { 020 021 /** 022 * Creates a composite list, inferring the element type from the arguments. 023 * 024 * @param lists One or more lists 025 * @param <T> element type 026 * @return composite list 027 */ 028 public static <T> List<T> of( 029 List<? extends T>... lists) 030 { 031 return CompositeList.<T>of(lists); 032 } 033 034 /** 035 * Creates a composite iterable, inferring the element type from the 036 * arguments. 037 * 038 * @param iterables One or more iterables 039 * @param <T> element type 040 * @return composite iterable 041 */ 042 public static <T> Iterable<T> of( 043 Iterable<? extends T>... iterables) 044 { 045 return new CompositeIterable<T>(iterables); 046 } 047 048 /** 049 * Creates a composite list, inferring the element type from the arguments. 050 * 051 * @param iterators One or more iterators 052 * @param <T> element type 053 * @return composite list 054 */ 055 public static <T> Iterator<T> of( 056 Iterator<? extends T>... iterators) 057 { 058 final Iterator[] iterators1 = (Iterator[]) iterators; 059 return new CompositeIterator<T>(iterators1); 060 } 061 062 private static class CompositeIterable<T> implements Iterable<T> { 063 private final Iterable<? extends T>[] iterables; 064 065 public CompositeIterable(Iterable<? extends T>[] iterables) { 066 this.iterables = iterables; 067 } 068 069 public Iterator<T> iterator() { 070 return new CompositeIterator(iterables); 071 } 072 } 073 074 private static class CompositeIterator<T> implements Iterator<T> { 075 private final Iterator<Iterator<T>> iteratorIterator; 076 private boolean hasNext; 077 private T next; 078 private Iterator<T> iterator; 079 080 public CompositeIterator(Iterator<T>[] iterables) { 081 this.iteratorIterator = Arrays.asList(iterables).iterator(); 082 this.iterator = Collections.<T>emptyList().iterator(); 083 this.hasNext = true; 084 advance(); 085 } 086 087 public CompositeIterator(final Iterable<T>[] iterables) { 088 this.iteratorIterator = 089 new IterableIterator<T>(iterables); 090 Arrays.asList(iterables).iterator(); 091 this.iterator = Collections.<T>emptyList().iterator(); 092 this.hasNext = true; 093 advance(); 094 } 095 096 private void advance() { 097 for (;;) { 098 if (iterator.hasNext()) { 099 next = iterator.next(); 100 return; 101 } 102 if (!iteratorIterator.hasNext()) { 103 hasNext = false; 104 break; 105 } 106 iterator = iteratorIterator.next(); 107 } 108 } 109 110 public boolean hasNext() { 111 return hasNext; 112 } 113 114 public T next() { 115 final T next1 = next; 116 advance(); 117 return next1; 118 } 119 120 public void remove() { 121 throw new UnsupportedOperationException(); 122 } 123 } 124 125 private static class IterableIterator<T> 126 implements Iterator<Iterator<T>> 127 { 128 private int i; 129 private final Iterable<T>[] iterables; 130 131 public IterableIterator(Iterable<T>[] iterables) { 132 this.iterables = iterables; 133 i = 0; 134 } 135 136 public boolean hasNext() { 137 return i < iterables.length; 138 } 139 140 public Iterator<T> next() { 141 return iterables[i++].iterator(); 142 } 143 144 public void remove() { 145 throw new UnsupportedOperationException(); 146 } 147 } 148} 149 150// End Composite.java