1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.efaps.db;
22
23 import java.sql.SQLException;
24 import java.util.ArrayList;
25 import java.util.HashSet;
26 import java.util.Iterator;
27 import java.util.List;
28 import java.util.Map;
29 import java.util.Map.Entry;
30 import java.util.Set;
31 import java.util.UUID;
32
33 import org.apache.commons.collections4.iterators.ReverseListIterator;
34 import org.efaps.admin.access.AccessTypeEnums;
35 import org.efaps.admin.datamodel.Attribute;
36 import org.efaps.admin.datamodel.AttributeType;
37 import org.efaps.admin.datamodel.SQLTable;
38 import org.efaps.admin.datamodel.Type;
39 import org.efaps.admin.event.EventType;
40 import org.efaps.ci.CIType;
41 import org.efaps.db.transaction.ConnectionResource;
42 import org.efaps.db.wrapper.SQLInsert;
43 import org.efaps.util.EFapsException;
44 import org.slf4j.Logger;
45 import org.slf4j.LoggerFactory;
46
47
48
49
50
51 public class Insert
52 extends Update
53 {
54
55
56
57
58 private static final Logger LOG = LoggerFactory.getLogger(Insert.class);
59
60
61
62
63 private long exchangeId = 0;
64
65
66
67
68 private long exchangeSystemId = 0;
69
70
71
72
73
74
75
76 public Insert(final Type _type) throws EFapsException
77 {
78 super(_type, null);
79 addCreateUpdateAttributes();
80 addTables();
81 }
82
83
84
85
86
87
88 public Insert(final String _type) throws EFapsException
89 {
90 this(Type.get(_type));
91 }
92
93
94
95
96
97
98 public Insert(final CIType _ciType) throws EFapsException
99 {
100 this(_ciType.uuid);
101 }
102
103
104
105
106
107
108 public Insert(final UUID _uuid) throws EFapsException
109 {
110 this(Type.get(_uuid));
111 }
112
113
114
115
116
117 private void addTables()
118 {
119 for (final SQLTable table : getType().getTables()) {
120 if (!getTable2values().containsKey(table)) {
121 getTable2values().put(table, new ArrayList<Value>());
122 }
123 }
124 }
125
126
127
128
129
130
131
132 private void addCreateUpdateAttributes() throws EFapsException
133 {
134 final Iterator<?> iter = getType().getAttributes().entrySet().iterator();
135 while (iter.hasNext()) {
136 final Map.Entry<?, ?> entry = (Map.Entry<?, ?>) iter.next();
137 final Attribute attr = (Attribute) entry.getValue();
138 final AttributeType attrType = attr.getAttributeType();
139 if (attrType.isCreateUpdate()) {
140 addInternal(attr, false, (Object) null);
141 }
142 if (attr.getDefaultValue() != null) {
143 addInternal(attr, false, attr.getDefaultValue());
144 }
145 }
146 }
147
148
149
150
151
152
153
154 public Insert setExchangeIds(final Long _exchangeSystemId,
155 final Long _exchangeId)
156 {
157 this.exchangeSystemId = _exchangeSystemId;
158 this.exchangeId = _exchangeId;
159 return this;
160 }
161
162
163
164
165 @Override
166 public void execute()
167 throws EFapsException
168 {
169 final boolean hasAccess = getType().hasAccess(Instance.get(getType(), 0),
170 AccessTypeEnums.CREATE.getAccessType(), getNewValuesMap());
171 if (!hasAccess) {
172 Insert.LOG.error("Insert not permitted for Person: {} on Type: {}", Context.getThreadContext().getPerson(),
173 getType());
174 throw new EFapsException(getClass(), "execute.NoAccess", getType());
175 }
176 executeWithoutAccessCheck();
177 }
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194 @Override
195 public void executeWithoutAccessCheck()
196 throws EFapsException
197 {
198 executeEvents(EventType.INSERT_PRE);
199 if (!executeEvents(EventType.INSERT_OVERRIDE)) {
200 executeWithoutTrigger();
201 }
202 executeEvents(EventType.INSERT_POST);
203 }
204
205
206
207
208
209
210
211 @Override
212 public void executeWithoutTrigger()
213 throws EFapsException
214 {
215 final Context context = Context.getThreadContext();
216 ConnectionResource con = null;
217 try {
218
219 con = context.getConnectionResource();
220
221 final SQLTable mainTable = getType().getMainTable();
222
223 final long id = executeOneStatement(con, mainTable, getTable2values().get(mainTable), 0);
224
225 setInstance(Instance.get(getInstance().getType(), id));
226
227 getInstance().setExchangeId(this.exchangeId);
228 getInstance().setExchangeSystemId(this.exchangeSystemId);
229
230 GeneralInstance.insert(getInstance(), con.getConnection());
231
232 for (final Entry<SQLTable, List<Value>> entry : getTable2values().entrySet()) {
233 final SQLTable table = entry.getKey();
234 if (!table.equals(mainTable) && !table.isReadOnly()) {
235 executeOneStatement(con, table, entry.getValue(), id);
236 }
237 }
238 con.commit();
239 } finally {
240 if (con != null && con.isOpened()) {
241 con.abort();
242 }
243 }
244 }
245
246
247
248
249 @Override
250 protected void validate(final Instance _instance,
251 final Value _value)
252 throws EFapsException
253 {
254 _value.getAttribute().getAttributeType().getDbAttrType()
255 .valiate4Insert(_value.getAttribute(), getInstance(), _value.getValues());
256 }
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273 private long executeOneStatement(final ConnectionResource _con,
274 final SQLTable _table,
275 final List<Value> _values,
276 final long _id)
277 throws EFapsException
278 {
279 Insert.LOG.debug("Preparing insert on table: {} for Values: {}", _table, _values);
280 long ret = _id;
281 try {
282 final SQLInsert insert = Context.getDbType().newInsert(_table.getSqlTable(),
283 _table.getSqlColId(),
284 _id == 0);
285
286 if (_id != 0) {
287 insert.column(_table.getSqlColId(), _id);
288 }
289 if (_table.getSqlColType() != null) {
290 insert.column(_table.getSqlColType(), getType().getId());
291 }
292
293 final ReverseListIterator<Value> iterator = new ReverseListIterator<Value>(_values);
294
295 final Set<String> added = new HashSet<String>();
296 while (iterator.hasNext()) {
297 final Value value = iterator.next();
298 final String colKey = value.getAttribute().getSqlColNames().toString();
299 if (!added.contains(colKey)) {
300 value.getAttribute().prepareDBInsert(insert, value.getValues());
301 added.add(colKey);
302 }
303 }
304
305 final Long bck = insert.execute(_con.getConnection());
306 if (bck != null) {
307 ret = bck;
308 }
309
310 } catch (final SQLException e) {
311 Insert.LOG.error("executeOneStatement", e);
312 throw new EFapsException(getClass(), "executeOneStatement.Exception", e, _table.getName());
313 }
314 return ret;
315 }
316 }