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.program;
22  
23  import java.io.IOException;
24  import java.io.InputStream;
25  import java.net.URL;
26  import java.util.Set;
27  
28  import org.apache.commons.jexl2.JexlContext;
29  import org.apache.commons.lang3.builder.ToStringBuilder;
30  import org.efaps.admin.datamodel.Type;
31  import org.efaps.db.Checkin;
32  import org.efaps.db.Context;
33  import org.efaps.update.AbstractUpdate;
34  import org.efaps.update.UpdateLifecycle;
35  import org.efaps.update.util.InstallationException;
36  import org.efaps.util.EFapsException;
37  
38  /**
39   * ABstract class for all kind of sources. eg. java, css, js.
40   *
41   * @author The eFaps Team
42   * @version $Id$
43   */
44  public abstract class AbstractSourceUpdate
45      extends AbstractUpdate
46  {
47      /**
48       * Constructor setting the Name of the Type to be imported/updated.
49       *
50       * @param _url URL to the file
51       * @param _modelTypeName name of the type
52       */
53      protected AbstractSourceUpdate(final URL _url,
54                                     final String _modelTypeName)
55      {
56          this(_url, _modelTypeName, null);
57      }
58  
59      /**
60       * Constructor setting the Name of the Type to be imported/updated.
61       *
62       * @param _url URL to the file
63       * @param _modelTypeName name of the type
64       * @param _linkTypes set of links
65       */
66      protected AbstractSourceUpdate(final URL _url,
67                                     final String _modelTypeName,
68                                     final Set<Link> _linkTypes)
69      {
70          super(_url, _modelTypeName, _linkTypes);
71      }
72  
73      /**
74       * Get the Version of this Update. Override id to use other than 1.
75       *
76       * @return always 1
77       */
78      protected Long getVersion()
79      {
80          return new Long(1);
81      }
82  
83      /**
84       * Throws always a new error because not allowed to call.
85       *
86       * @return nothing
87       */
88      @Override
89      protected AbstractDefinition newDefinition()
90      {
91          throw new Error("not allowed");
92      }
93  
94      /**
95       * Class used as the definition for one source.
96       */
97      public abstract class AbstractSourceDefinition
98          extends AbstractDefinition
99      {
100         /**
101          * Instance variable holding the URL to the file to be imported.
102          */
103         private URL fileUrl;
104 
105         /**
106          * Constructor to defined the URL in {@link #fileUrl} to the file and
107          * calculating the name of the source object (file url minus root url).
108          * The path separators are replaces by points.
109          *
110          * @param _fileUrl  URL to the file (incl. root).
111          */
112         protected AbstractSourceDefinition(final URL _fileUrl)
113         {
114             // searched by attribute Name
115             super("Name");
116             this.fileUrl = _fileUrl;
117         }
118 
119         /**
120          * Method to get the Revision from the importer.
121          * @return revision
122          * @throws InstallationException on error
123          */
124         protected abstract String getRevision() throws InstallationException;
125 
126         /**
127          * Updates / creates the instance in the database. If a file
128          * name is given, this file is checked in
129          *
130          * @param _step             current update step
131          * @param _allLinkTypes     set of links
132          * @throws InstallationException on error
133          *
134          */
135         @Override
136         public void updateInDB(final UpdateLifecycle _step,
137                                final Set<Link> _allLinkTypes)
138             throws InstallationException
139         {
140             // on update the revision must be set before the super method is called
141             if (_step == UpdateLifecycle.EFAPS_UPDATE)  {
142                 setFileRevision(getRevision());
143             }
144             super.updateInDB(_step, _allLinkTypes);
145 
146             if (_step == UpdateLifecycle.EFAPS_UPDATE && getValue("Name") != null)  {
147                 final Checkin checkin = new Checkin(getInstance());
148                 try {
149                     final InputStream in = this.fileUrl.openStream();
150                     checkin.executeWithoutAccessCheck(getValue("Name"),
151                                                       in,
152                                                       in.available());
153                     in.close();
154                 } catch (final IOException e) {
155                     throw new InstallationException("updateInDB.IOException", e);
156                 } catch (final EFapsException e) {
157                     throw new InstallationException("EFapsException", e);
158                 }
159             }
160         }
161 
162         @Override
163         public boolean isValidVersion(final JexlContext _jexlContext)
164             throws InstallationException
165         {
166             boolean ret =false;
167             try {
168                  ret = getDataModelTypeName() != null
169                                  && Type.isInitialized() && Type.get(getDataModelTypeName()) != null
170                                  && !Type.get(getDataModelTypeName()).getAttributes().isEmpty()
171                                  && Type.get(getDataModelTypeName()).getStoreId() > 0
172                                  && Context.getThreadContext().getPerson() != null;
173             } catch (final EFapsException e) {
174                 throw new InstallationException("Could not validate the version.", e);
175             }
176             return ret;
177         }
178 
179         /**
180          * This is the getter method for the instance variable
181          * {@link #fileUrl}.
182          *
183          * @return value of instance variable {@link #fileUrl}
184          */
185         public URL getUrl()
186         {
187             return this.fileUrl;
188         }
189 
190         /**
191          * This is the setter method for the instance variable
192          * {@link #fileUrl}.
193          *
194          * @param _url  the url to set
195          */
196         public void setUrl(final URL _url)
197         {
198             this.fileUrl = _url;
199         }
200 
201         /**
202          * Method returns a String representation of this class.
203          * @return String representation
204          */
205         @Override
206         public String toString()
207         {
208             return new ToStringBuilder(this)
209                 .appendSuper(super.toString())
210                 .append("url", this.fileUrl)
211                 .toString();
212         }
213     }
214 }