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.version;
22  
23  import java.io.File;
24  import java.io.IOException;
25  import java.text.ParseException;
26  import java.util.HashMap;
27  import java.util.HashSet;
28  import java.util.Map;
29  import java.util.Set;
30  
31  import org.apache.commons.digester3.annotations.rules.BeanPropertySetter;
32  import org.apache.commons.digester3.annotations.rules.CallMethod;
33  import org.apache.commons.digester3.annotations.rules.CallParam;
34  import org.apache.commons.digester3.annotations.rules.ObjectCreate;
35  import org.apache.commons.digester3.annotations.rules.SetProperty;
36  import org.apache.commons.lang3.builder.ToStringBuilder;
37  import org.apache.ivy.Ivy;
38  import org.apache.ivy.core.cache.ArtifactOrigin;
39  import org.apache.ivy.core.module.descriptor.Artifact;
40  import org.apache.ivy.core.module.id.ModuleRevisionId;
41  import org.apache.ivy.core.report.ArtifactDownloadReport;
42  import org.apache.ivy.core.resolve.DownloadOptions;
43  import org.apache.ivy.core.resolve.ResolveOptions;
44  import org.apache.ivy.core.resolve.ResolvedModuleRevision;
45  import org.apache.ivy.core.settings.IvySettings;
46  import org.efaps.update.Profile;
47  import org.efaps.update.util.InstallationException;
48  
49  /**
50   * Defines a dependency for an eFaps application. Existing dependency could be
51   * resolved.
52   *
53   * @author The eFaps Team
54   * @version $Id$
55   */
56  @ObjectCreate(pattern = "install/dependencies/dependency")
57  public class Dependency
58  {
59      /**
60       * Group identifier.
61       */
62      @BeanPropertySetter(pattern = "install/dependencies/dependency/groupId")
63      private String groupId;
64  
65  
66      /**
67       * Artifact identifier.
68       */
69      @BeanPropertySetter(pattern = "install/dependencies/dependency/artifactId")
70      private String artifactId;
71  
72      /**
73       * Version.
74       */
75      @BeanPropertySetter(pattern = "install/dependencies/dependency/version")
76      private String version;
77  
78      /**
79       * Link to the class file which is defined by this dependency.
80       *
81       * @see #resolve()
82       */
83      private File jarFile;
84  
85      /**
86       * Order position of this dependency.
87       */
88      @SetProperty(pattern = "install/dependencies/dependency/", attributeName = "order")
89      private Integer order;
90  
91      /**
92       * List of related profiles.
93       */
94      private final Set<String> profileNames = new HashSet<String>();
95  
96      /**
97       * Resolves this dependency.
98       *
99       * @throws InstallationException if dependency could not be resolved
100      *                               because the ivy settings could not be
101      *                               loaded
102      */
103     public void resolve()
104         throws InstallationException
105     {
106         final IvySettings ivySettings = new IvySettings();
107         try  {
108             ivySettings.load(this.getClass().getResource("/org/efaps/update/version/ivy.xml"));
109         } catch (final IOException e)  {
110             throw new InstallationException("IVY setting file could not be read", e);
111         } catch (final ParseException e)  {
112             throw new InstallationException("IVY setting file could not be parsed", e);
113         }
114 
115         final Ivy ivy = Ivy.newInstance(ivySettings);
116         ivy.getLoggerEngine().pushLogger(new IvyOverSLF4JLogger());
117 
118         final Map<String, String> attr = new HashMap<String, String>();
119         attr.put("changing", "true");
120 
121         final ModuleRevisionId modRevId = ModuleRevisionId.newInstance(this.groupId,
122                                                                        this.artifactId,
123                                                                        this.version,
124                                                                        attr);
125 
126         final ResolveOptions options = new ResolveOptions();
127         options.setConfs(new String[] {"runtime"});
128 
129 
130         final ResolvedModuleRevision resModRev = ivy.findModule(modRevId);
131 
132         Artifact dw = null;
133         for (final Artifact artifact : resModRev.getDescriptor().getAllArtifacts())  {
134             if ("jar".equals(artifact.getType()))  {
135                 dw = artifact;
136                 break;
137             }
138         }
139 
140         final DownloadOptions dwOptions = new DownloadOptions();
141 
142         final ArtifactOrigin ao = resModRev.getArtifactResolver().locate(dw);
143         resModRev.getArtifactResolver().getRepositoryCacheManager().clean();
144 
145         final ArtifactDownloadReport adw = resModRev.getArtifactResolver().download(ao, dwOptions);
146 
147         this.jarFile = adw.getLocalFile();
148     }
149 
150     /**
151      * Returns the related Jar file of this dependency.
152      *
153      * @return Jar file of this dependency
154      * @see #jarFile
155      */
156     public File getJarFile()
157     {
158         return this.jarFile;
159     }
160 
161     /**
162      * Getter method for the instance variable {@link #order}.
163      *
164      * @return value of instance variable {@link #order}
165      */
166     public Integer getOrder()
167     {
168         return this.order;
169     }
170 
171     /**
172      * Setter method for instance variable {@link #order}.
173      *
174      * @param _order value for instance variable {@link #order}
175      */
176 
177     public void setOrder(final Integer _order)
178     {
179         this.order = _order;
180     }
181 
182     /**
183      * Getter method for the instance variable {@link #groupId}.
184      *
185      * @return value of instance variable {@link #groupId}
186      */
187     public String getGroupId()
188     {
189         return this.groupId;
190     }
191 
192 
193     /**
194      * Setter method for instance variable {@link #groupId}.
195      *
196      * @param _groupId value for instance variable {@link #groupId}
197      */
198 
199     public void setGroupId(final String _groupId)
200     {
201         this.groupId = _groupId;
202     }
203 
204 
205     /**
206      * Getter method for the instance variable {@link #artifactId}.
207      *
208      * @return value of instance variable {@link #artifactId}
209      */
210     public String getArtifactId()
211     {
212         return this.artifactId;
213     }
214 
215 
216     /**
217      * Setter method for instance variable {@link #artifactId}.
218      *
219      * @param _artifactId value for instance variable {@link #artifactId}
220      */
221 
222     public void setArtifactId(final String _artifactId)
223     {
224         this.artifactId = _artifactId;
225     }
226 
227 
228     /**
229      * Getter method for the instance variable {@link #version}.
230      *
231      * @return value of instance variable {@link #version}
232      */
233     public String getVersion()
234     {
235         return this.version;
236     }
237 
238     /**
239      * Setter method for instance variable {@link #version}.
240      *
241      * @param _version value for instance variable {@link #version}
242      */
243 
244     public void setVersion(final String _version)
245     {
246         this.version = _version;
247     }
248 
249     /**
250      * @param _name name to add
251      */
252     @CallMethod(pattern = "install/dependencies/dependency/profiles/profile")
253     public void addProfileName(@CallParam(pattern = "install/dependencies/dependency/profiles/profile",
254                                                 attributeName = "name") final String _name)
255     {
256         this.profileNames.add(_name);
257     }
258 
259     /**
260      * Get the profiles for this dependency. In case that there are no profiles
261      * defined in {@link #profileNames} it will return a set containing the
262      * default profile.
263      *
264      * @return profiles applied for this dependency
265      */
266     public Set<Profile> getProfiles()
267     {
268         final Set<Profile> ret = new HashSet<Profile>();
269         if (this.profileNames.isEmpty()) {
270             ret.add(Profile.getDefaultProfile());
271         } else {
272             for (final String name : this.profileNames) {
273                 ret.add(Profile.getProfile(name));
274             }
275         }
276         return ret;
277     }
278 
279     /**
280      * Returns the information about this dependency as string representation.
281      *
282      * @return string representation
283      */
284     @Override
285     public String toString()
286     {
287         return new ToStringBuilder(this)
288                 .append("groupId", this.groupId)
289                 .append("artifactId", this.artifactId)
290                 .append("version", this.version)
291                 .append("order", this.order)
292                 .append("jarFile", this.jarFile)
293                 .toString();
294     }
295 }