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.common;
22  
23  import java.net.URL;
24  import java.util.ArrayList;
25  import java.util.List;
26  import java.util.Map;
27  import java.util.Set;
28  import java.util.UUID;
29  
30  import org.efaps.admin.user.Company;
31  import org.efaps.ci.CIAdminCommon;
32  import org.efaps.db.Insert;
33  import org.efaps.db.Instance;
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 system configurations for eFaps read from a
44   * XML configuration item file.
45   *
46   * @author The eFaps Team
47   * @version $Id$
48   */
49  public class SystemConfigurationUpdate
50      extends AbstractUpdate
51  {
52      /**
53       * Default constructor to initialize this system configuration update
54       * instance for given <code>_url</code>.
55       *
56       * @param _url        URL of the file
57       */
58      public SystemConfigurationUpdate(final URL _url)
59      {
60          super(_url, "Admin_Common_SystemConfiguration");
61      }
62  
63      /**
64       * Creates new instance of class {@link Definition}.
65       *
66       * @return new definition instance
67       * @see Definition
68       */
69      @Override
70      protected AbstractDefinition newDefinition()
71      {
72          return new Definition();
73      }
74  
75      /**
76       * Handles the definition of one version for an attribute definition
77       * defined within XML configuration item file.
78       */
79      public class AttributeDefinition
80          extends AbstractDefinition
81      {
82          /**
83           * Key of a property attribute.
84           */
85          private String key;
86  
87          /**
88           * Value of a property attribute.
89           */
90          private String value;
91  
92          /**
93           * Description of a property attribute.
94           */
95          private String description;
96  
97          /**
98           * UUID of a Company. Optional!
99           */
100         private String companyUUID;
101 
102         /**
103          *
104          * @param _tags         current path as list of single tags
105          * @param _attributes   attributes for current path
106          * @param _text         content for current path
107          * @throws EFapsException on error
108          */
109         @Override
110         protected void readXML(final List<String> _tags,
111                                final Map<String, String> _attributes,
112                                final String _text)
113             throws EFapsException
114         {
115             final String tmpValue = _tags.get(0);
116             if ("key".equals(tmpValue)) {
117                 this.key = _text;
118             } else if ("value".equals(tmpValue)) {
119                 this.value = _text;
120             } else if ("description".equals(tmpValue)) {
121                 this.description = _text;
122             } else if ("company".equals(tmpValue)) {
123                 this.companyUUID = _text;
124             } else {
125                 super.readXML(_tags, _attributes, _text);
126             }
127         }
128 
129         /**
130          * @param _instance     instance to update
131          * @throws EFapsException if update failed
132          */
133         public void updateInDB(final Instance _instance)
134             throws EFapsException
135         {
136             Company company = null;
137             if (this.companyUUID != null) {
138                 company = Company.get(UUID.fromString(this.companyUUID));
139             }
140             final QueryBuilder queryBldr = new QueryBuilder(CIAdminCommon.SystemConfigurationAttribute);
141             queryBldr.addWhereAttrEqValue(CIAdminCommon.SystemConfigurationAttribute.Key, this.key);
142             queryBldr.addWhereAttrEqValue(CIAdminCommon.SystemConfigurationAttribute.AbstractLink, _instance);
143             if (company == null) {
144                 queryBldr.addWhereAttrEqValue(CIAdminCommon.SystemConfigurationAttribute.CompanyLink, 0);
145             } else {
146                 queryBldr.addWhereAttrEqValue(CIAdminCommon.SystemConfigurationAttribute.CompanyLink, company.getId());
147             }
148             final InstanceQuery query = queryBldr.getQuery();
149             query.executeWithoutAccessCheck();
150             Update update = null;
151             if (query.next()) {
152                 update = new Update(query.getCurrentValue());
153             } else {
154                 update = new Insert(CIAdminCommon.SystemConfigurationAttribute);
155                 update.add(CIAdminCommon.SystemConfigurationAttribute.AbstractLink, _instance.getId());
156                 update.add(CIAdminCommon.SystemConfigurationAttribute.Key, this.key);
157             }
158             if (company != null) {
159                 update.add(CIAdminCommon.SystemConfigurationAttribute.CompanyLink, company.getId());
160             } else {
161                 update.add(CIAdminCommon.SystemConfigurationAttribute.CompanyLink, 0);
162             }
163             update.add(CIAdminCommon.SystemConfigurationAttribute.Value, this.value);
164             update.add(CIAdminCommon.SystemConfigurationAttribute.Description, this.description);
165             update.executeWithoutAccessCheck();
166         }
167     }
168 
169     /**
170      * Handles the definition of one version for an system configuration
171      * defined within XML configuration item file.
172      */
173     public class Definition
174         extends AbstractDefinition
175     {
176         /**
177          * Current parsed attribute definition.
178          *
179          * @see #readXML(List, Map, String)
180          */
181         private AttributeDefinition curAttr;
182 
183         /**
184          * List of all read attribute definition.
185          *
186          * @see #readXML(List, Map, String)
187          */
188         private final List<SystemConfigurationUpdate.AttributeDefinition> attributes
189             = new ArrayList<SystemConfigurationUpdate.AttributeDefinition>();
190 
191         /**
192          *
193          * @param _tags         current path as list of single tags
194          * @param _attributes   attributes for current path
195          * @param _text         content for current path
196          * @throws EFapsException on error
197          */
198         @Override
199         protected void readXML(final List<String> _tags,
200                                final Map<String, String> _attributes,
201                                final String _text)
202             throws EFapsException
203         {
204             final String value = _tags.get(0);
205             if ("attribute".equals(value)) {
206                 if (_tags.size() == 1) {
207                     this.curAttr = new AttributeDefinition();
208                     this.attributes.add(this.curAttr);
209                 } else {
210                     this.curAttr.readXML(_tags.subList(1, _tags.size()), _attributes, _text);
211                 }
212             } else {
213                 super.readXML(_tags, _attributes, _text);
214             }
215         }
216 
217         /**
218          * If the current life cycle <code>step</code> is
219          * {@link UpdateLifecycle#EFAPS_UPDATE EFAPS_UPDATE}, the
220          * {@link #attributes} are updated.
221          *
222          * @param _step             current life cycle update step
223          * @param _allLinkTypes     all link types to update
224          * @throws InstallationException if update failed
225          * @see #attributes
226          */
227         @Override
228         public void updateInDB(final UpdateLifecycle _step,
229                                final Set<Link> _allLinkTypes)
230             throws InstallationException
231         {
232             super.updateInDB(_step, _allLinkTypes);
233             try {
234                 if (_step == UpdateLifecycle.EFAPS_UPDATE)  {
235                     for (final AttributeDefinition attr : this.attributes) {
236                         attr.updateInDB(getInstance());
237                     }
238                 }
239             } catch (final EFapsException e) {
240                 throw new InstallationException(" Type can not be updated", e);
241             }
242         }
243     }
244 }