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.db;
22  
23  import java.net.URL;
24  import java.util.List;
25  import java.util.Map;
26  import java.util.Set;
27  
28  import org.efaps.ci.CIDB;
29  import org.efaps.db.Insert;
30  import org.efaps.db.Instance;
31  import org.efaps.db.MultiPrintQuery;
32  import org.efaps.db.QueryBuilder;
33  import org.efaps.db.SelectBuilder;
34  import org.efaps.db.Update;
35  import org.efaps.db.store.Store;
36  import org.efaps.update.AbstractUpdate;
37  import org.efaps.update.UpdateLifecycle;
38  import org.efaps.update.util.InstallationException;
39  import org.efaps.util.EFapsException;
40  
41  /**
42   * Handles the import / update of stores for eFaps read from a XML configuration
43   * item file.
44   *
45   * @author The eFaps Team
46   * @version $Id$
47   */
48  public class StoreUpdate
49      extends AbstractUpdate
50  {
51  
52      /**
53       * @param _url url to the XML file
54       */
55      public StoreUpdate(final URL _url)
56      {
57          super(_url, "DB_Store");
58      }
59  
60      /**
61       * Creates a new definition instance used from
62       * {@link #readXML(List, Map, String)}.
63       *
64       * @return new definition instance
65       */
66      @Override
67      protected AbstractDefinition newDefinition()
68      {
69          return new StoreDefinition();
70      }
71  
72      /**
73       * Definition for a Resource.
74       */
75      protected final class ResourceDefinition
76          extends AbstractDefinition
77      {
78  
79          /**
80           * Name of the class.
81           */
82          private final String clazz;
83  
84          /**
85           * @param _class name of the class
86           * @param _compress compress
87           */
88          private ResourceDefinition(final String _class,
89                                     final String _compress)
90          {
91              this.clazz = _class;
92              getProperties().put(Store.PROPERTY_COMPRESS, _compress);
93          }
94  
95          /**
96           * Read the xml.
97           *
98           * @see AbstractDefinition#readXML(List, Map, String)
99           * @param _tags list of tags
100          * @param _attributes attributes
101          * @param _text text
102          * @throws EFapsException on error
103          */
104         @Override
105         protected void readXML(final List<String> _tags,
106                                final Map<String, String> _attributes,
107                                final String _text)
108             throws EFapsException
109         {
110             super.readXML(_tags, _attributes, _text);
111         }
112     }
113 
114     /**
115      * Definition for a store.
116      *
117      */
118     protected class StoreDefinition
119         extends AbstractDefinition
120     {
121 
122         /**
123          * Resource definition for htis store.
124          */
125         private ResourceDefinition resource;
126 
127         /**
128          * Read the XML.
129          *
130          * @param _tags List of tags
131          * @param _attributes map of attributes
132          * @param _text text
133          * @throws EFapsException on error
134          */
135         @Override
136         protected void readXML(final List<String> _tags,
137                                final Map<String, String> _attributes,
138                                final String _text)
139             throws EFapsException
140         {
141             final String value = _tags.get(0);
142             if ("resource".equals(value)) {
143                 if (_tags.size() == 1) {
144                     this.resource = new ResourceDefinition(_attributes.get("class"),
145                                     _attributes.get("compress"));
146                 } else {
147                     this.resource.readXML(_tags.subList(1, _tags.size()), _attributes, _text);
148                 }
149             } else if ("jndi-name".equals(value)) {
150                 getProperties().put(Store.PROPERTY_JNDINAME, _text);
151             } else {
152                 super.readXML(_tags, _attributes, _text);
153             }
154         }
155 
156         /**
157          * Update the store in the database.
158          *
159          * @param _step current life cycle update step
160          * @param _allLinkTypes set of all links
161          * @throws InstallationException on error
162          * @see AbstractUpdate.AbstractDefinition#updateInDB(UpdateLifecycle,Set)
163          */
164         @Override
165         public void updateInDB(final UpdateLifecycle _step,
166                                final Set<Link> _allLinkTypes)
167             throws InstallationException
168         {
169             super.updateInDB(_step, _allLinkTypes);
170             if (_step == UpdateLifecycle.EFAPS_UPDATE) {
171                 setSourceInDB();
172             }
173         }
174 
175         /**
176          * @throws InstallationException o error
177          */
178         private void setSourceInDB()
179             throws InstallationException
180         {
181             try {
182                 boolean old = false;
183                 final Update update;
184                 final QueryBuilder queryBldr = new QueryBuilder(CIDB.Store2Resource);
185                 queryBldr.addWhereAttrEqValue(CIDB.Store2Resource.From, getInstance().getId());
186                 final MultiPrintQuery multi = queryBldr.getPrint();
187                 final SelectBuilder sel = new SelectBuilder().linkto(CIDB.Store2Resource.To).oid();
188                 multi.addSelect(sel);
189                 multi.executeWithoutAccessCheck();
190                 if (multi.next()) {
191                     final Instance resourceInst = Instance.get(multi.<String> getSelect(sel));
192                     update = new Update(resourceInst);
193                     old = true;
194                 } else {
195                     update = new Insert(CIDB.Resource);
196                 }
197                 update.add(CIDB.Resource.Name, this.resource.clazz);
198                 update.executeWithoutAccessCheck();
199                 setPropertiesInDb(update.getInstance(), this.resource.getProperties());
200 
201                 if (!old) {
202                     final Insert insert = new Insert(CIDB.Store2Resource);
203                     insert.add(CIDB.Store2Resource.From, getInstance().getId());
204                     insert.add(CIDB.Store2Resource.To, update.getInstance().getId());
205                     insert.executeWithoutAccessCheck();
206                     insert.close();
207                 }
208                 update.close();
209             } catch (final EFapsException e) {
210                 throw new InstallationException("source can not be set in the DB", e);
211             }
212         }
213     }
214 }