View Javadoc

1   /**
2    * Copyright 2005-2006 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.SortableEntityObject;
18  import org.figure8.join.core.InvalidParameterException;
19  import org.figure8.join.services.vcs.VCSAccessor;
20  import org.figure8.join.util.LogUtil;
21  
22  import org.apache.commons.logging.Log;
23  
24  import java.text.MessageFormat;
25  /**
26   * Entity object representing a deliverable type. Such a type helps
27   * categorizing work deliveries done and managed through Join application.
28   * <br/>
29   * A deliverable type will help by knowing how to generate unique keys for
30   * deliverable artifacts. (see the <code>generateDeliverableKey()</code> method)
31   * <br/>
32   * It is also a handler for all the connection informations to the
33   * underlying Versionning and Configuration System ; in the case such a
34   * system is used for retrieving deliverables. (see the <code>getVCSAccessor()</code>
35   * method)
36   * @author  <a href="mailto:laurent.broudoux@free.fr">Laurent Broudoux</a>
37   * @version $Revision: 1.3 $
38   *
39   * @see org.figure8.join.services.vcs.VCSAccessor
40   *
41   * @hibernate.class table="join_deltypes"
42   * @hibernate.cache usage="read-write"
43   *
44   * @hibernate.query name="join.deltype_findByKey" query="from DeliverableType type where type.key = :typeKey"
45   */
46  public class DeliverableType extends SortableEntityObject{
47  
48     // Static -------------------------------------------------------------------
49  
50     /** Get a commons logger. */
51     private static final Log log = LogUtil.getLog(DeliverableType.class);
52  
53  
54     // Attributes ---------------------------------------------------------------
55  
56     /** The deliverable type key */
57     private String key;
58     /** The deliverable type label */
59     private String label;
60     /** The deliverable type keyTemplate */
61     private String keyTemplate;
62     /** The deliverable type is versionnable */
63     private boolean versionable;
64     /** The deliverable type is mandatory */
65     private boolean mandatory;
66     /** The deliverable type use version and configuration system */
67     private boolean vcsDeliverable = false;
68  
69     /** User for connecting to the version and configuration system */
70     private String vcsUser;
71     /** Password for connecting to the version and configuration system */
72     private String vcsPassword;
73     /** The root of the version and configuration system */
74     private String vcsRoot;
75     /** The module of the version and configuration system */
76     private String vcsModule;
77     /** The accessor class name for the version and configuration system */
78     private String vcsAccessorClass;
79  
80     /** The template object for generating deliverable keys */
81     private MessageFormat template = null;
82     /** The VCS accessor instance of type <b>vcsAccessorClass</b> */
83     private VCSAccessor vcsAccessor = null;
84  
85  
86     // Constructors -------------------------------------------------------------
87  
88     /** Creates a new instance of DeliverableType */
89     public DeliverableType(){
90     }
91  
92     /**
93      * Creates a new instance of DeliverableType with mandatory attributes
94      * @param key The instance unique key
95      * @param label The type instance label
96      * @param keyTemplate The deliverable type template for key generation
97      * @param versionable Wether deliverables should appear in versions
98      * @param mandatory Wether deliverables are mandatory in version composition
99      * @see org.figure8.join.businessobjects.artifact.Assembly
100     */
101    public DeliverableType(String key, String label, String keyTemplate, boolean versionable, boolean mandatory){
102       this.key = key;
103       this.label = label;
104       this.keyTemplate = keyTemplate;
105       this.versionable = versionable;
106       this.mandatory = mandatory;
107    }
108 
109 
110    // Public -------------------------------------------------------------------
111 
112    /**
113     * @hibernate.property column="s_key"
114     *    length="10" not-null="true"
115     *    unique="true" update="false"
116     * @return This deliverable type key
117     */
118    public String getKey(){
119       return key;
120    }
121    /** @param key This type unique key */
122    public void setKey(String key){
123       this.key = key;
124    }
125 
126    /**
127     * @hibernate.property column="s_label"
128     *    length="40" not-null="true"
129     *    unique="true"
130     * @return This type label for display
131     */
132    public String getLabel(){
133       return label;
134    }
135    /** @param label This deliverable type label */
136    public void setLabel(String label){
137       this.label = label;
138    }
139 
140    /**
141     * @hibernate.property column="s_keytemplate"
142     *    length="40" not-null="true"
143     *    unique="true"
144     * @return The template used for generating deliverable keys
145     */
146    public String getKeyTemplate(){
147       return keyTemplate;
148    }
149    /**
150     * The template used for deliverables key generation. This template
151     * should be a string representing a <code>MessageFormat</code> with
152     * 2 arguments. (ex: myDeliverable_r{0}_v{1})
153     * @param keyTemplate MessageFormat template
154     * @see java.text.MessageFormat
155     */
156    public void setKeyTemplate(String keyTemplate){
157       this.keyTemplate = keyTemplate;
158    }
159 
160    /**
161     * @hibernate.property column="b_versionable"
162     *    type="boolean" not-null="true"
163     * @return true if deliverables of this type should be used for
164     *    composing a <code>Assembly</code>
165     * @see org.figure8.join.businessobjects.artifact.Assembly
166     */
167    public boolean getVersionable(){
168       return versionable;
169    }
170    /** @param versionable Wether deliverables are used for composing <code>Versions</code> */
171    public void setVersionable(boolean versionable){
172       this.versionable = versionable;
173    }
174 
175    /**
176     * @hibernate.property column="b_mandatory"
177     *    type="boolean" not-null="true"
178     * @return true if deliverables of this type are mandatory when
179     *    used for composing a <code>Assembly</code>
180     * @see org.figure8.join.businessobjects.artifact.Assembly
181     */
182    public boolean getMandatory(){
183       return mandatory;
184    }
185    /** @param mandatory Wether deliverables are mandatory whe composing <code>Versions</code> */
186    public void setMandatory(boolean mandatory){
187       this.mandatory = mandatory;
188    }
189 
190    /**
191     * @hibernate.property column="b_vcsdeliverable"
192     *    type="boolean" not-null="true"
193     * @return true if deliverables of this type are retrieved using
194     *    a version and configuration system (such as CVS, Subversion, ...)
195     */
196    public boolean getVcsDeliverable(){
197       return vcsDeliverable;
198    }
199    /** @param vcsDeliverable Wether deliverables are retrieved using a version and configuration system */
200    public void setVcsDeliverable(boolean vcsDeliverable){
201       this.vcsDeliverable = vcsDeliverable;
202    }
203 
204    /**
205     * @hibernate.property column="s_vcsuser" length="30"
206     * @return The user for connecting to version and configuration system
207     */
208    public String getVcsUser(){
209       return vcsUser;
210    }
211    /** @param vcsUser The user for connecting to VCS */
212    public void setVcsUser(String vcsUser){
213       this.vcsUser = vcsUser;
214    }
215 
216    /**
217     * @hibernate.property column="s_vcspassword" length="30"
218     * @return The password for connecting to version and configuration system
219     */
220    public String getVcsPassword(){
221       return vcsPassword;
222    }
223    /** @param vcsPassword The password for connection to VCS */
224    public void setVcsPassword(String vcsPassword){
225       this.vcsPassword = vcsPassword;
226    }
227 
228    /**
229     * @hibernate.property column="s_vcsroot" length="100"
230     * @return The root of version and configuration system used (might be a CVS root, a Subversion Url, etc ...)
231     */
232    public String getVcsRoot(){
233       return vcsRoot;
234    }
235    /** @param vcsRoot The root of VCS used (CVS root, SVN Url, ...) */
236    public void setVcsRoot(String vcsRoot){
237       this.vcsRoot = vcsRoot;
238    }
239 
240    /**
241     * @hibernate.property column="s_vcsmodule" length="40"
242     * @return Name of module corresponding to deliverables in VCS (CVS module, "trunk" for Subversion, etc ..)
243     */
244    public String getVcsModule(){
245       return vcsModule;
246    }
247    /** @param vcsModule Name of module corresponding to deliverables in VCS */
248    public void setVcsModule(String vcsModule){
249       this.vcsModule = vcsModule;
250    }
251 
252    /**
253     * @hibernate.property column="s_vcsaccessorclass" length="200"
254     * @return The FQN of the Java class used for connecting version and
255     *    configuration system corresponding to this type
256     */
257    public String getVcsAccessorClass(){
258       return vcsAccessorClass;
259    }
260    /**
261     * Assign a VCS implementation to this deliverable type. ie : an helper object that allows
262     * to connect to the version and configuration system used for retrieving deliverables of
263     * this type. This parameter must be the name of the Java class that implements
264     * <code>org.figure8.join.services.vcs.VCSAccessor</code>
265     * @param vcsAccessorClass FQN of Java class
266     * @throws org.figure8.join.core.InvalidParameterException if the <b>vcsImplementationClass</b> is not valid
267     */
268    public void setVcsAccessorClass(String vcsAccessorClass) throws InvalidParameterException{
269       this.vcsAccessorClass = vcsAccessorClass;
270       // Try instantiating VCS accessor now.
271       instantiateVCSAccessor();
272    }
273 
274    /**
275     * Get the <code>VCSAccessor</code> associated to this type (if any). The returned accessor
276     * is "ready to use" : it has been initialized with corret properties.
277     * @throws InvalidParameterException if the <b>vcsAccessorClass</b> inner field is not valid
278     * @return The accessor instance or null if no accessor is associated to this role
279     */
280    public VCSAccessor getVCSAccessor() throws InvalidParameterException{
281       // Only available if deliverable trough VCS and if there's a accessor defined.
282       if (vcsDeliverable && vcsAccessorClass != null){
283          // Instantiate if not already done.
284          if (vcsAccessor == null)
285             instantiateVCSAccessor();
286          // Set vcs accessor fields.
287          vcsAccessor.setUser(vcsUser);
288          vcsAccessor.setPassword(vcsPassword);
289          vcsAccessor.setModule(vcsModule);
290          vcsAccessor.setRootRepository(vcsRoot);
291          // Ok.
292          return vcsAccessor;
293       }
294       return null;
295    }
296 
297    /**
298     * Generate a unique key for a deliverable. Such a key has to be unique as
299     * specified by the <code>Artifact</code>. So this implementation is using
300     * the given <b>keyTemplate</b> as a java.text.MessageFormat using 2 arguments
301     * that are the deliverable release name (unique for a relase) and the deliverable
302     * version infos (unique for a deliverable within a release).
303     * @param deliverable Deliverable for whom a key should be generated
304     * @return A unique key corresponding to this deliverable. The key is not
305     *    assigned to deliverable.
306     * @see java.text.MessageFormat
307     * @see org.figure8.join.businessobjects.artifact.Artifact
308     */
309    public String generateDeliverableKey(Deliverable deliverable){
310       // Instantiate a message format if not already done.
311       if (template == null)
312          template = new MessageFormat(keyTemplate);
313       // Prepare and format arguments array.
314       Object[] args = new Object[]{deliverable.getRelease().getName(), deliverable.getVersionInfo()};
315       return template.format(args);
316    }
317 
318 
319    // Protected ----------------------------------------------------------------
320 
321    /**
322     * Try to instantiate the <code>VCSAccessor</code> associated with this type (if any ...)
323     * @throws InvalidParameterException if the <b>vcsAccessorClass</b> inner field is not valid
324     */
325    protected void instantiateVCSAccessor() throws InvalidParameterException{
326       if (vcsAccessorClass != null && vcsAccessor == null){
327          try{
328             // Load class from context class loader and retrieve new instance.
329             Class clazz = Thread.currentThread().getContextClassLoader().loadClass(vcsAccessorClass);
330             vcsAccessor = (VCSAccessor)clazz.newInstance();
331          }
332          catch (Exception e){
333             // Log and wrap within an InvalidParameterException.
334             log.error("Exception while trying to instantiate vcsAccessor for deliverable type '" + key + "'");
335             log.error("Here's the exception message : " + e.getMessage());
336             throw new InvalidParameterException("'" + vcsAccessorClass +
337                     "' cannot be found or does not extend VCSAccessor", e);
338          }
339       }
340    }
341 
342 
343    // Implementation of SortableEntityObect ------------------------------------
344 
345    /**
346     * Get the comparision criterion as a string. Display label here.
347     * @return The string representation of comparison and sort cirterion
348     */
349    public String getStringForComparison(){
350       return getLabel();
351    }
352 }