1 /*
2 * Copyright 2003 - 2013 The eFaps Team
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 * Revision: $Rev$
17 * Last Changed: $Date$
18 * Last Changed By: $Author$
19 */
20
21 package org.efaps.update.schema.datamodel;
22
23 import java.net.URL;
24 import java.util.HashSet;
25 import java.util.List;
26 import java.util.Map;
27 import java.util.Set;
28
29 import org.efaps.admin.datamodel.Attribute;
30 import org.efaps.admin.datamodel.Dimension;
31 import org.efaps.admin.datamodel.Type;
32 import org.efaps.ci.CIAdminDataModel;
33 import org.efaps.db.Insert;
34 import org.efaps.db.InstanceQuery;
35 import org.efaps.db.QueryBuilder;
36 import org.efaps.db.Update;
37 import org.efaps.update.AbstractUpdate;
38 import org.efaps.update.UpdateLifecycle;
39 import org.efaps.update.util.InstallationException;
40 import org.efaps.util.EFapsException;
41
42 /**
43 * Handles the import / update of status groups for eFaps read from a XML
44 * configuration item file. Remark: The StatusGroupDefinition is actual just a
45 * normal Admin_DataModel_Type and the stati belonging to it are instances of
46 * this Type. That leads to the problem that if a StatusGroupUpdate is executed
47 * in one version the cache for the Types must be reloaded.
48 *
49 * @author The eFaps Team
50 * @version $Id$
51 */
52 public class StatusGroupUpdate
53 extends AbstractUpdate
54 {
55
56 /**
57 * Default constructor to initialize this status group instance for given
58 * <code>_url</code>.
59 *
60 * @param _url url to the file
61 */
62 public StatusGroupUpdate(final URL _url)
63 {
64 super(_url, "Admin_DataModel_Type");
65 }
66
67 /**
68 * {@inheritDoc}
69 */
70 @Override
71 protected AbstractDefinition newDefinition()
72 {
73 return new StatusGroupDefinition();
74 }
75
76 /**
77 * Definition of one status.
78 */
79 public class StatusDefintion
80 {
81
82 /**
83 * Key of this status.
84 */
85 private final String key;
86
87 /**
88 * Description for this status.
89 */
90 private String description;
91
92 /**
93 * @param _key key
94 */
95 public StatusDefintion(final String _key)
96 {
97 this.key = _key;
98 }
99
100 /**
101 * @param _description description
102 */
103 public void setDescription(final String _description)
104 {
105 this.description = _description;
106 }
107
108 /**
109 * @param _typeName name of the type
110 * @throws EFapsException on error during insert
111 */
112 public void updateInDB(final String _typeName)
113 throws EFapsException
114 {
115 final QueryBuilder queryBldr = new QueryBuilder(Type.get(_typeName));
116 queryBldr.addWhereAttrEqValue("Key", this.key);
117 final InstanceQuery query = queryBldr.getQuery();
118 query.executeWithoutAccessCheck();
119 final Update update;
120 if (query.next()) {
121 update = new Update(query.getCurrentValue());
122 } else {
123 update = new Insert(_typeName);
124 }
125 update.add("Key", this.key);
126 update.add("Description", this.description);
127 update.executeWithoutAccessCheck();
128 }
129 }
130
131 /**
132 * Class for the definition of the type.
133 */
134 public class StatusGroupDefinition
135 extends AbstractDefinition
136 {
137
138 /**
139 * Name of the parent type.
140 */
141 private String parentType;
142
143 /**
144 * current definition.
145 */
146 private StatusDefintion currentStatus;
147
148 /**
149 * Set of all definitions.
150 */
151 private final Set<StatusGroupUpdate.StatusDefintion> stati = new HashSet<StatusGroupUpdate.StatusDefintion>();
152
153 /**
154 *
155 * @param _tags current path as list of single tags
156 * @param _attributes attributes for current path
157 * @param _text content for current path
158 * @throws EFapsException on error
159 */
160 @Override
161 protected void readXML(final List<String> _tags,
162 final Map<String, String> _attributes,
163 final String _text)
164 throws EFapsException
165 {
166 final String value = _tags.get(0);
167 if ("status".equals(value)) {
168 if (_tags.size() == 1) {
169 this.currentStatus = new StatusDefintion(_attributes.get("key"));
170 this.stati.add(this.currentStatus);
171 } else if (_tags.size() == 2 && "description".equals(_tags.get(1))) {
172 this.currentStatus.setDescription(_text);
173 }
174 } else if ("parent".equals(value)) {
175 this.parentType = _text;
176 } else {
177 super.readXML(_tags, _attributes, _text);
178 }
179 }
180
181 /**
182 * If a parent type in {@link #parentType} is defined, the type id is
183 * evaluated and added to attributes to update (if no parent type is
184 * defined, the parent type id is set to <code>null</code>). After the
185 * type is updated (or inserted if needed), all statis must be updated.
186 *
187 * @param _step current step in the Update Lifecycle
188 * @param _allLinkTypes set of all links
189 * @throws InstallationException on error
190 * @see #parentType
191 * @see #attributes
192 */
193 @Override
194 public void updateInDB(final UpdateLifecycle _step,
195 final Set<Link> _allLinkTypes)
196 throws InstallationException
197 {
198 try {
199 if (_step == UpdateLifecycle.STATUSGROUP_CREATE) {
200 super.updateInDB(UpdateLifecycle.EFAPS_CREATE, _allLinkTypes);
201 }
202
203 if (_step == UpdateLifecycle.STATUSGROUP_UPDATE) {
204 // set the id of the parent type (if defined)
205 if ((this.parentType != null) && (this.parentType.length() > 0)) {
206 final QueryBuilder queryBldr = new QueryBuilder(CIAdminDataModel.Type);
207 queryBldr.addWhereAttrEqValue(CIAdminDataModel.Type.Name, this.parentType);
208 final InstanceQuery query = queryBldr.getQuery();
209 query.executeWithoutAccessCheck();
210 if (query.next()) {
211 addValue("ParentType", "" + query.getCurrentValue().getId());
212 } else {
213 addValue("ParentType", null);
214 }
215 } else {
216 addValue("ParentType", null);
217 }
218 super.updateInDB(UpdateLifecycle.EFAPS_UPDATE, _allLinkTypes);
219 }
220
221 if (_step == UpdateLifecycle.STATUS_CREATE) {
222 // before the Stati can be created it must be checked if the
223 // type (StatusGroup)
224 // is already cached.
225 if (Type.get(getValue("Name")) == null) {
226 Type.initialize(StatusGroupUpdate.class);
227 Dimension.initialize(StatusGroupUpdate.class);
228 Attribute.initialize(StatusGroupUpdate.class);
229 }
230 for (final StatusDefintion status : this.stati) {
231 status.updateInDB(getValue("Name"));
232 }
233 }
234 } catch (final EFapsException e) {
235 throw new InstallationException(" SQLTable can not be updated", e);
236 }
237 }
238 }
239 }