1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package com.healthmarketscience.jackcess.impl;
18
19 import java.io.IOException;
20 import java.util.EnumSet;
21 import java.util.Set;
22
23 import com.healthmarketscience.jackcess.Column;
24 import com.healthmarketscience.jackcess.DataType;
25 import com.healthmarketscience.jackcess.PropertyMap;
26 import com.healthmarketscience.jackcess.complex.ComplexColumnInfo;
27 import com.healthmarketscience.jackcess.complex.ComplexDataType;
28 import com.healthmarketscience.jackcess.impl.complex.MultiValueColumnInfoImpl;
29
30
31
32
33
34
35
36
37
38
39 public class ComplexColumnDesc
40 {
41
42 private static final Set<DataType> VALUE_TYPES = EnumSet.of(
43 DataType.BYTE, DataType.INT, DataType.LONG, DataType.FLOAT,
44 DataType.DOUBLE, DataType.GUID, DataType.NUMERIC, DataType.TEXT);
45
46
47 private final ComplexDataType _type;
48
49 private final DataType _valueType;
50
51 private final String _memoColumnName;
52
53 private String _rowSourceType;
54
55 private String _rowSource;
56
57 private int _columnCount = 1;
58
59 private ComplexColumnDesc(ComplexDataType type, DataType valueType,
60 String memoColumnName) {
61 _type = type;
62 _valueType = valueType;
63 _memoColumnName = memoColumnName;
64 }
65
66 public static ComplexColumnDesc multiValue(DataType valueType) {
67 return new ComplexColumnDesc(ComplexDataType.MULTI_VALUE, valueType, null);
68 }
69
70 public static ComplexColumnDesc attachment() {
71 return new ComplexColumnDesc(ComplexDataType.ATTACHMENT, null, null);
72 }
73
74 public static ComplexColumnDesc versionHistory(String memoColumnName) {
75 return new ComplexColumnDesc(ComplexDataType.VERSION_HISTORY, null,
76 memoColumnName);
77 }
78
79
80
81
82
83
84
85
86 public static ComplexColumnDesc fromColumn(Column template)
87 throws IOException
88 {
89 ComplexColumnInfo<?> info = template.getComplexInfo();
90 if(info == null) {
91 return null;
92 }
93
94 switch(info.getType()) {
95 case ATTACHMENT:
96 return attachment();
97 case MULTI_VALUE:
98 Column valueCol = ((MultiValueColumnInfoImpl)info).getValueColumn();
99 ComplexColumnDesc desc = multiValue(valueCol.getType());
100 PropertyMap props = valueCol.getProperties();
101 desc.setRowSource(
102 (String)props.getValue(PropertyMap.ROW_SOURCE_TYPE_PROP),
103 (String)props.getValue(PropertyMap.ROW_SOURCE_PROP),
104 toColumnCount(props.getValue(PropertyMap.COLUMN_COUNT_PROP)));
105 return desc;
106 case VERSION_HISTORY:
107 throw noVersionHistoryCopy("Column=" + template.getName());
108 default:
109 throw new IllegalArgumentException(
110 "Cannot copy a complex column of a kind jackcess cannot read " +
111 "(Column=" + template.getName() + ")");
112 }
113 }
114
115 private static int toColumnCount(Object value) {
116 return ((value instanceof Number) ? ((Number)value).intValue() : 1);
117 }
118
119
120
121
122 public ComplexColumnDesc copy() {
123 if(_type == ComplexDataType.VERSION_HISTORY) {
124
125
126 throw noVersionHistoryCopy("MemoColumn=" + _memoColumnName);
127 }
128 ComplexColumnDesc/ComplexColumnDesc.html#ComplexColumnDesc">ComplexColumnDesc desc = new ComplexColumnDesc(_type, _valueType,
129 _memoColumnName);
130 desc.setRowSource(_rowSourceType, _rowSource, _columnCount);
131 return desc;
132 }
133
134 private static IllegalArgumentException noVersionHistoryCopy(String what) {
135 return new IllegalArgumentException(
136 "A version history column follows the memo column it holds the " +
137 "versions of, so it is copied with setAppendOnly on that column " +
138 "rather than on its own (" + what + ")");
139 }
140
141 public ComplexDataType getType() {
142 return _type;
143 }
144
145 public DataType getValueType() {
146 return _valueType;
147 }
148
149 public String getMemoColumnName() {
150 return _memoColumnName;
151 }
152
153 public String getRowSourceType() {
154 return _rowSourceType;
155 }
156
157 public String getRowSource() {
158 return _rowSource;
159 }
160
161 public int getColumnCount() {
162 return _columnCount;
163 }
164
165 public void setRowSource(String rowSourceType, String rowSource,
166 int columnCount) {
167 _rowSourceType = rowSourceType;
168 _rowSource = rowSource;
169 _columnCount = columnCount;
170 }
171
172
173
174
175
176
177 public void validate(String colName) {
178 if(_type != ComplexDataType.MULTI_VALUE) {
179 return;
180 }
181 if(!VALUE_TYPES.contains(_valueType)) {
182 throw new IllegalArgumentException(
183 "A multi-value column holds values of type " + VALUE_TYPES +
184 ", not " + _valueType + " (Column=" + colName + ")");
185 }
186
187
188
189 if((_rowSource == null) || _rowSource.isEmpty()) {
190 throw new IllegalArgumentException(
191 "A multi-value column needs a row source, from either setValueList " +
192 "or setRowSource (Column=" + colName + ")");
193 }
194 }
195
196 @Override
197 public String toString() {
198 return ToStringBuilder.builder(this)
199 .append("type", _type)
200 .appendIfNotNull("valueType", _valueType)
201 .appendIfNotNull("memoColumn", _memoColumnName)
202 .appendIfNotNull("rowSourceType", _rowSourceType)
203 .appendIfNotNull("rowSource", _rowSource)
204 .toString();
205 }
206 }