View Javadoc

1   /**
2    * Copyright 2005-2007 the original author or authors.
3    *
4    * Licensed under the Gnu General Pubic License, Version 2.0 (the
5    * "License"); you may not use this file except in compliance with
6    * the License. You may obtain a copy of the License at
7    *
8    *      http://www.opensource.org/licenses/gpl-license.php
9    *
10   * This program is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13   * See the Gnu General Public License for more details.
14   */
15  package org.figure8.join.businessobjects.artifact;
16  
17  import org.figure8.join.core.EntityObject;
18  import org.figure8.join.core.ContainerContextHandler;
19  import org.figure8.join.core.setup.ApplicationConfig;
20  import org.figure8.join.businessobjects.commons.Status;
21  import org.figure8.join.businessobjects.commons.Release;
22  import org.figure8.join.util.LogUtil;
23  
24  import org.apache.commons.logging.Log;
25  
26  import java.util.Map;
27  import java.util.Date;
28  import java.util.List;
29  import java.util.HashMap;
30  import java.util.ArrayList;
31  import java.text.MessageFormat;
32  /**
33   * An assembly if a composite artifact build from deliverables.
34   * It represents a subset of the future software system you are
35   * building.
36   * <br/>
37   * During the construction phase of Assembly, software components
38   * are discovered and thus bound to this entity.
39   * <br/>
40   * Assemblies are meant for being deployed on test environments.
41   *
42   * @author  <a href="mailto:laurent.broudoux@free.fr">Laurent Broudoux</a>
43   * @version $Revision: 1.4 $
44   *
45   * @hibernate.class table="join_assemblies" lazy="true"
46   * @hibernate.cache usage="read-write"
47   *
48   * @hibernate.query name="join.assembly_findByKey"
49   *    query="from Assembly ass left join fetch ass.components where ass.key = :assKey"
50   * @hibernate.query name="join.assembly_findByComposerId"
51   *    query="from Assembly ass where ass.composerId = :userId order by ass.creationDate desc"
52   * @hibernate.query name="join.assembly_findByRelease"
53   *    query="from Assembly ass where ass.release = :assRelease order by ass.creationDate desc"
54   * @hibernate.query name="join.assembly_findWithDeliverables"
55   *    query="from Assembly ass join ass.deliverables del where del in elements(:deliverableList)"
56   */
57  public class Assembly extends EntityObject implements Artifact{
58  
59     // Static -------------------------------------------------------------------
60  
61     /** Get a commons logger. */
62     private static final Log log = LogUtil.getLog(Assembly.class);
63  
64     /** Constant denoting the applicative property defining the template for assemblies key */
65     public static final String KEY_TEMPLATE = "assembly.key.template";
66     /** Constant for the default assemblies key generation template (in case we are not in managed environment) */
67     public static final String DEFAULT_KEY_TEMPLATE = "assembly-r{0}-v{1}";
68  
69     /** The template object for generating assembly keys. */
70     private static MessageFormat template = null;
71  
72  
73     // Attributes ---------------------------------------------------------------
74  
75     /** The assembly key */
76     private String key;
77     /** The assembly comments */
78     private String comments;
79     /** Assembly version info */
80     private String versionInfo;
81     /** The assembly creation date */
82     private Date creationDate;
83     /** The identifier of user that has composed assembly */
84     private String composerId;
85     /** A map containing components. Keys are component types, values are components entity */
86     private Map components = new HashMap();
87     /** A map containing deliverables. Keys are deliverable types, values are deliverables entity */
88     private Map deliverables = new HashMap();
89     /** A list of deployments done with this assembly */
90     private List deployments = new ArrayList();
91  
92     /** The assembly current status */
93     private Status status;
94     /** The release for which assembly is created */
95     private Release release;
96     
97     
98     // Constructors -------------------------------------------------------------
99     
100    /** Creates a new instance of Assembly */
101    public Assembly(){
102    }
103 
104    /**
105     * Creates a new instance of Assembly with mandatory attributes.
106     * @param versionInfo Information of this assembly version
107     * @param comments Comments onto assembly
108     * @param composerId The identifier of user that has compoed assembly
109     * @param release The release for which assembly is created
110     */
111    public Assembly(String versionInfo, String comments, String composerId, Release release){
112       // Initialize fields.
113       this.comments = comments;
114       this.versionInfo = versionInfo;
115       this.composerId = composerId;
116       this.release = release;
117       this.creationDate = new Date();
118       // Now we have all needed infos, generate a key.
119       this.key = generateAssemblyKey(this);
120    }
121 
122 
123    // Public -------------------------------------------------------------------
124 
125    /**
126     * @hibernate.property column="s_key"
127     *    length="40" not-null="true"
128     *    unique="true" update="false"
129     * @return This assembly unique key
130     */
131    public String getKey(){
132       return key;
133    }
134    /** @param key This assembly unique key */
135    public void setKey(String key){
136       this.key = key;
137    }
138    
139    /**
140     * @hibernate.property column="s_comments" length="255"
141     * @return The comments on this Assembly
142     */
143    public String getComments(){
144       return comments;
145    }
146    /** @param comments The comments on this assembly */
147    public void setComments(String comments){
148       this.comments = comments;
149    }
150 
151    /** @param versionInfo Information on this assembly version within release */
152    public void setVersionInfo(String versionInfo){
153       this.versionInfo = versionInfo;
154    }
155 
156    /**
157     * @hibernate.property column="d_creation"
158     *    not-null="true" type="timestamp"
159     *    update="false"
160     * @return Creation date of this version
161     */
162    public Date getCreationDate(){
163       return creationDate;
164    }
165    /** @param creationDate The creation date of this assembly */
166    public void setCreationDate(Date creationDate){
167       this.creationDate = creationDate;
168    }
169 
170    /**
171     * @hibernate.property column="s_composerid"
172     *    length="20" not-null="true"
173     * @return The id of user that composes assembly
174     */
175    public String getComposerId(){
176       return composerId;
177    }
178    /** @param composerId The id of user that has composed this assembly */
179    public void setComposerId(String composerId){
180       this.composerId = composerId;
181    }
182    
183    /**
184     * @hibernate.many-to-one column="n_status_fk"
185     * @return The current status of this Assembly
186     */
187    public Status getStatus(){
188       return status;
189    }
190    /** @param status The current status of this assembly */
191    public void setStatus(Status status){
192       this.status = status;
193    }
194 
195    /** @param release Release this assembly has been done for */
196    public void setRelease(Release release){
197       this.release = release;
198    }
199    
200    /**
201     * @hibernate.map cascade="save-update" lazy="true" batch-size="10" table="assemblies_components"
202     * @hibernate.collection-key column="n_assembly_fk"
203     * @hibernate.index-many-to-many column="n_componenttype_fk"
204     *    class="org.figure8.join.businessobjects.artifact.ComponentType"
205     * @hibernate.collection-many-to-many column="n_component_fk"
206     *    class="org.figure8.join.businessobjects.artifact.Component" outer-join="true"
207     * @return A map of components contained in assembly, keys are component types.
208     */
209    public Map getComponents(){
210       return components;
211    }
212    /** @param components A map of components contained in assembly */
213    public void setComponents(Map components){
214       this.components = components;
215    }
216 
217    /**
218     * Convenient method for adding a components to an assembly.
219     * This method manages the 2 sides of the association.
220     * @param component The component to add to assembly
221     */
222    public void addComponent(Component component){
223       // Manage the 2 sides of relation.
224       components.put(component.getComponentType(), component);
225       if (!component.getAssemblies().contains(this))
226          component.getAssemblies().add(this);
227    }
228    /**
229     * Convenient method for retrieving only one component contained assembly
230     * @param type The ComponentType of component to return
231     * @return The corresponding {@link Component}
232     */
233    public Component getComponent(ComponentType type){
234       return (Component)components.get(type);
235    }
236 
237    /**
238     * @hibernate.map cascade="save-update" lazy="true" batch-size="5" table="assemblies_deliverables"
239     * @hibernate.collection-key column="n_assembly_fk"
240     * @hibernate.index-many-to-many column="n_deliverabletype_fk"
241     *    class="org.figure8.join.businessobjects.artifact.DeliverableType"
242     * @hibernate.collection-many-to-many column="n_deliverable_fk"
243     *    class="org.figure8.join.businessobjects.artifact.Deliverable" outer-join="true"
244     * @return A map of deliverables contained in assembly, keys are deliverable types.
245     */
246    public Map getDeliverables(){
247       return deliverables;  
248    }
249    /** @param deliverables A map of deliverables contained in assembly, keys are deliverable types */
250    public void setDeliverables(Map deliverables){
251       this.deliverables = deliverables;
252    }
253 
254    /**
255     * Convenient method for adding a deliverable to an assembly.
256     * This method manages the 2 sides of the association.
257     * @param deliverable The deliverable to add to assembly
258     */
259    public void addDeliverable(Deliverable deliverable){
260       // Managed the 2 sides of relation.
261       deliverables.put(deliverable.getDeliverableType(), deliverable);
262       deliverable.getAssemblies().add(this);
263    }
264    /**
265     * Convenient method for retrieving only one deliverable composing assembly
266     * @param type The DeliverableType of deliverable to return
267     * @return The corresponding {@link Deliverable}
268     */
269    public Deliverable getDeliverable(DeliverableType type){
270       return (Deliverable)deliverables.get(type);
271    }
272 
273    /**
274     * @hibernate.bag inverse="true" lazy="true"
275     * @hibernate.collection-key column="n_assembly_fk"
276     * @hibernate.collection-one-to-many class="org.figure8.join.businessobjects.environment.Deployment"
277     * @return A set of {@code Deployment}s made with this assembly
278     */
279    public List getDeployments(){
280       return deployments;
281    }
282    /** @param deployments The set of deployments made with this assembly */
283    public void setDeployments(List deployments){
284       this.deployments = deployments;
285    }
286 
287 
288    // Implementation of Artifact -----------------------------------------------
289 
290    /**
291     * Retrieve the unique identifier of this artifact. (ie : it's key)
292     * @return The unique identifier of this version
293     */
294    public String getUniqueId(){
295       return key;
296    }
297 
298    /**
299     * Retrieve the version information on this Assembly.
300     * @hibernate.property column="s_version"
301     *    length="20" not-null="true"
302     * @return Version information as character string
303     */
304    public String getVersionInfo(){
305       return versionInfo;
306    }
307 
308    /**
309     * Return the category information on this artifact (or null
310     * is this artifact implementation is not typed).
311     * @return The category information as character string
312     */
313    public String getCategoryInfo(){
314       return null;
315    }
316 
317    /**
318     * Retrieve the release that has cause this version creation
319     * @hibernate.many-to-one column="n_release_fk"
320     *    not-null="true" outer-join="false"
321     * @return The release this version has been realized for
322     */
323    public Release getRelease(){
324       return release;
325    }
326 
327 
328    // Protected ----------------------------------------------------------------
329 
330    /**
331     * Generate a unique key for an assembly. Such a key has to be unique as
332     * specified by the <code>Artifact</code>. So this implementation is using
333     * a java.text.MessageFormat using 2 arguments that are the assembly release name
334     * (unique for a relase) and the assembly version infos (unique for an assembly
335     * within a release).<br/>
336     * The <code>template</code> used as MessageFormat can be specified using the
337     * <i>assembly.key.template</i> property of {@link ApplicationConfig} object present
338     * into runtime environment. If this property or ApplicationConfig are not present
339     * ito environment, then the default key template is used.
340     * <br/>
341     * @param assembly Assembly for whom a key should be generated
342     * @return A unique key corresponding to this assembly. The key is not assigned to assembly.
343     * @see java.text.MessageFormat
344     * @see org.figure8.join.businessobjects.artifact.Artifact
345     */
346    protected static String generateAssemblyKey(Assembly assembly){
347       if (template == null){
348          String keyTemplate = null;
349          try{
350             // Try retrieving template from configured application property.
351             ContainerContextHandler handler = ContainerContextHandler.getInstance();
352             ApplicationConfig config = (ApplicationConfig)handler.getComponent("applicationConfig");
353             keyTemplate = config.getProperty(KEY_TEMPLATE);
354             if (keyTemplate == null)
355                keyTemplate = DEFAULT_KEY_TEMPLATE;
356          }
357          catch (Exception e){
358             // Use default key template.
359             log.warn("Exception while retrieving configured key template: " + e.getMessage());
360             log.warn("Using default key template: " + DEFAULT_KEY_TEMPLATE);
361             keyTemplate = DEFAULT_KEY_TEMPLATE;
362          }
363          template = new MessageFormat(keyTemplate);
364       }
365       // Prepare and format arguments array.
366       Object[] args = new Object[]{assembly.getRelease().getName(), assembly.getVersionInfo()};
367       return template.format(args);
368    }
369 }