OSDN Git Service

add LogWriter interface to enable switch log format
[xerial/xerial-core.git] / src / main / java / org / xerial / lens / relation / Tuple.java
1 /*--------------------------------------------------------------------------\r
2  *  Copyright 2009 Taro L. Saito\r
3  *\r
4  *  Licensed under the Apache License, Version 2.0 (the "License");\r
5  *  you may not use this file except in compliance with the License.\r
6  *  You may obtain a copy of the License at\r
7  *\r
8  *     http://www.apache.org/licenses/LICENSE-2.0\r
9  *\r
10  *  Unless required by applicable law or agreed to in writing, software\r
11  *  distributed under the License is distributed on an "AS IS" BASIS,\r
12  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
13  *  See the License for the specific language governing permissions and\r
14  *  limitations under the License.\r
15  *--------------------------------------------------------------------------*/\r
16 //--------------------------------------\r
17 // XerialJ\r
18 //\r
19 // Tuple.java\r
20 // Since: 2009/05/13 9:19:34\r
21 //\r
22 // $URL$\r
23 // $Author$\r
24 //--------------------------------------\r
25 package org.xerial.lens.relation;\r
26 \r
27 import java.util.ArrayList;\r
28 import java.util.Collection;\r
29 import java.util.Collections;\r
30 import java.util.Comparator;\r
31 import java.util.Iterator;\r
32 import java.util.List;\r
33 \r
34 import org.xerial.core.XerialError;\r
35 import org.xerial.core.XerialErrorCode;\r
36 \r
37 /**\r
38  * Tuple is a list of {@link TupleElement}s. This Tuple class allows Non-1NF\r
39  * representation of the data.\r
40  * \r
41  * @author leo\r
42  * \r
43  */\r
44 public class Tuple<Element> implements TupleElement<Element>, Iterable<TupleElement<Element>> {\r
45 \r
46     private final List<TupleElement<Element>> nodeList;\r
47 \r
48     public Tuple() {\r
49         this.nodeList = new ArrayList<TupleElement<Element>>();\r
50     }\r
51 \r
52     public Tuple(Tuple<Element> other) {\r
53         this(other.nodeList);\r
54     }\r
55 \r
56     public Tuple(int tupleSize) {\r
57         this.nodeList = new ArrayList<TupleElement<Element>>(tupleSize);\r
58     }\r
59 \r
60     public Tuple(List<TupleElement<Element>> nodeList) {\r
61         this.nodeList = new ArrayList<TupleElement<Element>>(nodeList.size());\r
62         for (TupleElement<Element> each : nodeList) {\r
63             this.nodeList.add(each);\r
64         }\r
65     }\r
66 \r
67     public void add(TupleElement<Element> node) {\r
68         nodeList.add(node);\r
69     }\r
70 \r
71     public void set(int index, TupleElement<Element> node) {\r
72         nodeList.set(index, node);\r
73     }\r
74 \r
75     public void set(TupleIndex index, TupleElement<Element> node) {\r
76         if (!index.hasTail()) {\r
77             set(index.get(0), node);\r
78             return;\r
79         }\r
80 \r
81         // nested node\r
82         TupleElement<Element> target = get(index.get(0));\r
83         if (target == null || !target.isTuple())\r
84             throw new XerialError(XerialErrorCode.INVALID_STATE, String.format(\r
85                     "set to invalid element: index = %s in %s", index, this));\r
86 \r
87         ((Tuple<Element>) target).set(index.tail(), node);\r
88     }\r
89 \r
90     public int size() {\r
91         return nodeList.size();\r
92     }\r
93 \r
94     public void clear() {\r
95         nodeList.clear();\r
96     }\r
97 \r
98     public boolean isEmpty() {\r
99         return nodeList.isEmpty();\r
100     }\r
101 \r
102     public void sort(Comparator<TupleElement<Element>> comparator) {\r
103         Collections.sort(nodeList, comparator);\r
104     }\r
105 \r
106     public Iterator<TupleElement<Element>> iterator() {\r
107         return nodeList.iterator();\r
108     }\r
109 \r
110     public TupleElement<Element> get(int index) {\r
111         return nodeList.get(index);\r
112     }\r
113 \r
114     private static <T> String join(Collection<T> c, String concatinator) {\r
115         if (c == null)\r
116             return "";\r
117         int size = c.size();\r
118         if (size == 0)\r
119             return "";\r
120 \r
121         Iterator<T> it = c.iterator();\r
122         StringBuilder buf = new StringBuilder();\r
123         for (int i = 0; it.hasNext() && i < size - 1; i++) {\r
124             Object data = it.next();\r
125             if (data != null)\r
126                 buf.append(data.toString());\r
127             else\r
128                 buf.append("null");\r
129             buf.append(concatinator);\r
130         }\r
131         Object lastData = it.next();\r
132         if (lastData != null)\r
133             buf.append(lastData.toString());\r
134         else\r
135             buf.append("null");\r
136         return buf.toString();\r
137     }\r
138 \r
139     @Override\r
140     public String toString() {\r
141         return String.format("[%s]", join(nodeList, ", "));\r
142     }\r
143 \r
144     public boolean addAll(List<TupleElement<Element>> relationFragment) {\r
145         return nodeList.addAll(relationFragment);\r
146     }\r
147 \r
148     public Element castToElement() {\r
149         return null;\r
150     }\r
151 \r
152     public Tuple<Element> castToTuple() {\r
153         return this;\r
154     }\r
155 \r
156     public boolean isAtom() {\r
157         return true;\r
158     }\r
159 \r
160     public boolean isTuple() {\r
161         return true;\r
162     }\r
163 \r
164     public TupleElement<Element> get(TupleIndex index) {\r
165         TupleElement<Element> cell = nodeList.get(index.get(0));\r
166         if (index.hasTail())\r
167             return cell.get(index.tail());\r
168         else\r
169             return cell;\r
170     }\r
171 \r
172     @SuppressWarnings("unchecked")\r
173     public Element getNode(int index) {\r
174         TupleElement<Element> node = get(index);\r
175         if (node.isAtom())\r
176             return (Element) node;\r
177         else\r
178             throw new XerialError(XerialErrorCode.MISSING_ELEMENT, "node is not found: " + index);\r
179     }\r
180 \r
181     @SuppressWarnings("unchecked")\r
182     public Element getElement(TupleIndex index) {\r
183         TupleElement<Element> node = get(index);\r
184         if (node == null)\r
185             return null;\r
186 \r
187         if (node.isAtom())\r
188             return (Element) node;\r
189         else\r
190             throw new XerialError(XerialErrorCode.MISSING_ELEMENT, "node is not found: " + index);\r
191 \r
192     }\r
193 \r
194     public Tuple<Element> flatten() {\r
195         ArrayList<TupleElement<Element>> array = new ArrayList<TupleElement<Element>>();\r
196         flatten(array, this);\r
197         return new Tuple<Element>(array);\r
198     }\r
199 \r
200     private void flatten(List<TupleElement<Element>> result, TupleElement<Element> cell) {\r
201         if (cell.isAtom())\r
202             result.add(cell);\r
203         else {\r
204             for (TupleElement<Element> each : cell.castToTuple()) {\r
205                 flatten(result, each);\r
206             }\r
207         }\r
208     }\r
209 \r
210     public void accept(TupleElementVisitor<Element> visitor) {\r
211         visitor.visitTuple(this);\r
212     }\r
213 \r
214 }\r