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.HashMap;
29  import java.text.MessageFormat;
30  /**
31   * A build if a composite artifact build from components.
32   * It represents a version of the software system you are building.
33   * <br/>
34   * Builds are meant for being deployed on production environnements.
35   * 
36   * @author  <a href="mailto:laurent.broudoux@free.fr">Laurent Broudoux</a>
37   * @version $Revision: 1.4 $
38   *
39   * @hibernate.class table="join_builds" lazy="true"
40   * @hibernate.cache usage="read-write"
41   *
42   * @hibernate.query name="join.build_findByKey"
43   *    query="from Build build where build.key = :buildKey"
44   * @hibernate.query name="join.build_findByComposerId"
45   *    query="from Build build where build.composerId = :userId order by build.creationDate desc"
46   * @hibernate.query name="join.build_findByRelease"
47  *    query="from Build build where build.release = :buildRelease order by build.creationDate desc"
48   */
49  public class Build extends EntityObject implements Artifact{
50  
51     // Static -------------------------------------------------------------------
52  
53     /** Get a commons logger. */
54     private static final Log log = LogUtil.getLog(Build.class);
55  
56     /** Constant denoting the applicative property defining the template for build keys */
57     public static final String KEY_TEMPLATE = "build.key.template";
58     /** Constant for the default builds key generation template (in case we are not in managed environment) */
59     public static final String DEFAULT_KEY_TEMPLATE = "build-r{0}-v{1}";
60  
61     /** The template object for generating build keys. */
62     private static MessageFormat template = null;
63  
64  
65     // Attributes ---------------------------------------------------------------
66     
67     /** The build unique key */
68     private String key;
69     /** The build comments */
70     private String comments;
71     /** The build version info */
72     private String versionInfo;
73     /** The build creation date */
74     private Date creationDate;
75     /** The identifier of user that has composed build */
76     private String composerId;
77     /** A map containing components. Keys are component types, values are components entity */
78     private Map components = new HashMap();
79     
80     /** The build current status */
81     private Status status;
82     /** The build release for which build is created */
83     private Release release;
84  
85     
86     // Constructors -------------------------------------------------------------
87     
88     /** Creates a new instance of Build */
89     public Build(){
90     }
91     
92     /**
93      * Creates a new instance of Build with mandatory attributes
94      * @param versionInfo Information of this build version
95      * @param comments Comments onto assembly
96      * @param composerId The identifier of user that has compoed assembly
97      * @param release The release for which assembly is created
98      */
99     public Build(String versionInfo, String comments, String composerId, Release release){
100       // Initialize fields.
101       this.comments = comments;
102       this.versionInfo = versionInfo;
103       this.composerId = composerId;
104       this.release = release;
105       this.creationDate = new Date();
106       // Now we have all needed infos, generate a key.
107       this.key = generateBuildKey(this);
108    }
109    
110    
111    // Public -------------------------------------------------------------------
112   
113    /**
114     * @hibernate.property column="s_key"
115     *    length="40" not-null="true"
116     *    unique="true" update="false"
117     * @return This build unique key
118     */
119    public String getKey(){
120       return key;
121    }
122    /** @param key This build unique key */
123    public void setKey(String key){
124       this.key = key;
125    }
126    
127    /**
128     * @hibernate.property column="s_comments" length="255"
129     * @return The comments on this Build
130     */
131    public String getComments(){
132       return comments;
133    }
134    /** @param comments The comments on this build */
135    public void setComments(String comments){
136       this.comments = comments;
137    }
138 
139    /** @param versionInfo Information on this build version within release */
140    public void setVersionInfo(String versionInfo){
141       this.versionInfo = versionInfo;
142    }
143    
144    /**
145     * @hibernate.property column="d_creation"
146     *    not-null="true" type="timestamp"
147     *    update="false"
148     * @return Creation date of this build
149     */
150    public Date getCreationDate(){
151       return creationDate;
152    }
153    /** @param creationDate The creation date of this build */
154    public void setCreationDate(Date creationDate){
155       this.creationDate = creationDate;
156    }
157    
158    /**
159     * @hibernate.property column="s_composerid"
160     *    length="20" not-null="true"
161     * @return The id of user that composes build
162     */
163    public String getComposerId(){
164       return composerId;
165    }
166    /** @param composerId The id of user that has composed this build */
167    public void setComposerId(String composerId){
168       this.composerId = composerId;
169    }
170    
171    /**
172     * @hibernate.many-to-one column="n_status_fk"
173     * @return The current status of this Build
174     */
175    public Status getStatus(){
176       return status;
177    }
178    /** @param status The current status of this build */
179    public void setStatus(Status status){
180       this.status = status;
181    }
182 
183    /** @param release Release this build has been done for */
184    public void setRelease(Release release){
185       this.release = release;
186    }
187  
188    /**
189     * @hibernate.map cascade="save-update" lazy="true" batch-size="10" table="builds_components"
190     * @hibernate.collection-key column="n_build_fk"
191     * @hibernate.index-many-to-many column="n_componenttype_fk"
192     *    class="org.figure8.join.businessobjects.artifact.ComponentType"
193     * @hibernate.collection-many-to-many column="n_component_fk"
194     *    class="org.figure8.join.businessobjects.artifact.Component" outer-join="true"
195     * @return A map of components contained in build, keys are component types.
196     */
197    public Map getComponents(){
198       return components;
199    }
200    /** @param components A map of components contained in build */
201    public void setComponents(Map components){
202       this.components = components;
203    }
204 
205    /**
206     * Convenient method for adding a components to a build.
207     * This method manages the 2 sides of the association.
208     * @param component The component to add to assembly
209     */
210    public void addComponent(Component component){
211       // Manage the 2 sides of relation.
212       components.put(component.getComponentType(), component);
213       component.getBuilds().add(this);
214    }
215    
216    
217    // Implementation of Artifact -----------------------------------------------
218 
219    /**
220     * Retrieve the unique identifier of this artifact. (ie : it's key)
221     * @return The unique identifier of this version
222     */
223    public String getUniqueId(){
224       return key;
225    }
226 
227    /**
228     * Retrieve the version information on this Assembly.
229     * @hibernate.property column="s_version"
230     *    length="20" not-null="true"
231     * @return Version information as character string
232     */
233    public String getVersionInfo(){
234       return versionInfo;
235    }
236 
237    /**
238     * Return the category information on this artifact (or null
239     * is this artifact implementation is not typed).
240     * @return The category information as character string
241     */
242    public String getCategoryInfo(){
243       return null;
244    }
245 
246    /**
247     * Retrieve the release that has cause this version creation
248     * @hibernate.many-to-one column="n_release_fk"
249     *    not-null="true" outer-join="false"
250     * @return The release this version has been realized for
251     */
252    public Release getRelease(){
253       return release;
254    }
255 
256 
257    // Protected ----------------------------------------------------------------
258 
259    /**
260     * Generate a unique key for an assembly. Such a key has to be unique as
261     * specified by the <code>Artifact</code>. So this implementation is using
262     * a java.text.MessageFormat using 2 arguments that are the build release name
263     * (unique for a relase) and the build version infos (unique for a build
264     * within a release).<br/>
265     * The <code>template</code> used as MessageFormat can be specified using the
266     * <i>build.key.template</i> property of {@link ApplicationConfig} object present
267     * into runtime environment. If this property or ApplicationConfig are not present
268     * ito environment, then the default key template is used.
269     * <br/>
270     * @param build Build for whom a key should be generated
271     * @return A unique key corresponding to this build. The key is not assigned to build.
272     * @see java.text.MessageFormat
273     * @see org.figure8.join.businessobjects.artifact.Artifact
274     */
275    protected static String generateBuildKey(Build build){
276       if (template == null){
277          String keyTemplate = null;
278          try{
279             // Try retrieving template from configured application property.
280             ContainerContextHandler handler = ContainerContextHandler.getInstance();
281             ApplicationConfig config = (ApplicationConfig)handler.getComponent("applicationConfig");
282             keyTemplate = config.getProperty(KEY_TEMPLATE);
283             if (keyTemplate == null)
284                keyTemplate = DEFAULT_KEY_TEMPLATE;
285          }
286          catch (Exception e){
287             // Use default key template.
288             log.warn("Exception while retrieving configured key template: " + e.getMessage());
289             log.warn("Using default key template: " + DEFAULT_KEY_TEMPLATE);
290             keyTemplate = DEFAULT_KEY_TEMPLATE;
291          }
292          template = new MessageFormat(keyTemplate);
293       }
294       // Prepare and format arguments array.
295       Object[] args = new Object[]{build.getRelease().getName(), build.getVersionInfo()};
296       return template.format(args);
297    }
298 }