View Javadoc

1   package org.apache.maven.werkz;
2   
3   /* ====================================================================
4    *   Licensed to the Apache Software Foundation (ASF) under one or more
5    *   contributor license agreements.  See the NOTICE file distributed with
6    *   this work for additional information regarding copyright ownership.
7    *   The ASF licenses this file to You under the Apache License, Version 2.0
8    *   (the "License"); you may not use this file except in compliance with
9    *   the License.  You may obtain a copy of the License at
10   *
11   *       http://www.apache.org/licenses/LICENSE-2.0
12   *
13   *   Unless required by applicable law or agreed to in writing, software
14   *   distributed under the License is distributed on an "AS IS" BASIS,
15   *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   *   See the License for the specific language governing permissions and
17   *   limitations under the License.
18   * ====================================================================
19   */
20  
21  /*
22   $Id: WerkzProject.java 517014 2007-03-11 21:15:50Z ltheussl $
23  
24   Copyright 2002 (C) The Werken Company. All Rights Reserved.
25   
26   Redistribution and use of this software and associated documentation
27   ("Software"), with or without modification, are permitted provided
28   that the following conditions are met:
29  
30   1. Redistributions of source code must retain copyright
31   statements and notices.  Redistributions must also contain a
32   copy of this document.
33   
34   2. Redistributions in binary form must reproduce the
35   above copyright notice, this list of conditions and the
36   following disclaimer in the documentation and/or other
37   materials provided with the distribution.
38   
39   3. The name "werkz" must not be used to endorse or promote
40   products derived from this Software without prior written
41   permission of The Werken Company.  For written permission,
42   please contact bob@werken.com.
43   
44   4. Products derived from this Software may not be called "werkz"
45   nor may "werkz" appear in their names without prior written
46   permission of The Werken Company. "werkz" is a registered
47   trademark of The Werken Company.
48   
49   5. Due credit should be given to "the werkz project"
50   ( http://werkz.werken.com/ ).
51   
52   THIS SOFTWARE IS PROVIDED BY THE WERKEN COMPANY AND CONTRIBUTORS
53   ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
54   NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
55   FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
56   THE WERKEN COMPANY OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
57   INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
58   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
59   SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
60   HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
61   STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
62   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
63   OF THE POSSIBILITY OF SUCH DAMAGE.
64   
65   */
66  
67  import java.util.Collection;
68  import java.util.Collections;
69  import java.util.HashMap;
70  import java.util.Iterator;
71  import java.util.LinkedList;
72  import java.util.List;
73  import java.util.Map;
74  
75  /** General <code>Goal</code> manager.
76   *
77   *  <p>
78   *  It is not strictly necessary to maintain a <code>Goal</code>
79   *  graph, it does assist in organizing and administering a
80   *  group of <code>Goal</code>s.
81   *
82   *  @see Goal
83   *
84   *  @author <a href="mailto:bob@eng.werken.com">bob mcwhirter</a>
85   */
86  public class WerkzProject
87  {
88      // ------------------------------------------------------------
89      //     Instance members
90      // ------------------------------------------------------------
91  
92      /** Goal index. */
93      private Map goals;
94  
95      /** Name of the default gual, or null. */
96      private String defaultGoalName;
97  
98      // ------------------------------------------------------------
99      //     Constructors
100     // ------------------------------------------------------------
101 
102     /** Construct.
103      */
104     public WerkzProject()
105     {
106         this.goals = new HashMap();
107     }
108 
109     // ------------------------------------------------------------
110     //     Instance methods
111     // ------------------------------------------------------------
112 
113     /** Retrieve a valid execution chain to attain the specified goal.
114      *
115      *  <p>
116      *  This method returns one of possibly many different valid
117      *  execution chains.  All chains will be of the same length.
118      *  This implementation happens to perform a breadth-first
119      *  walk, so the chain will grow from the deepest sections
120      *  to the showllowest instead of plunging/surging upwards.
121      *  <p>
122      *
123      *  <p>
124      *  <pre>
125      *        B - D
126      *      /       \
127      *    A           F
128      *      \       /
129      *        C - E
130      *  </pre>
131      *
132      *  will result in either FEDCBA or FDEBCA but will
133      *  not result in the equally valid FECDBA or FDBECA
134      *  sequences.
135      *  </p>
136      *
137      *  <p>
138      *  The ordering of the array is such that the index
139      *  <code>length - 1</code> (the last index of the array)
140      *  points to the <code>Goal</code> specified as the
141      *  parameter to the method.
142      *  </p>
143      *
144      *  @param name The name of the goal.
145      *
146      *  @return The array of goals in the execution chain, terminating
147      *          with the requested goal as the last member.
148      *
149      *  @throws NoSuchGoalException if the <code>name</code> refers to no known goal.
150      */
151 
152     public Goal[] getExecutionChain( String name )
153         throws NoSuchGoalException
154     {
155         Goal goal = getGoal( name );
156 
157         LinkedList chain = new LinkedList();
158         LinkedList stack = new LinkedList();
159 
160         stack.addLast( goal );
161 
162         while ( !stack.isEmpty() )
163         {
164             goal = (Goal) stack.removeFirst();
165 
166             if ( chain.contains( goal ) )
167             {
168                 continue;
169             }
170 
171             chain.addFirst( goal );
172 
173             List precursors = goal.getPrecursors();
174 
175             for ( Iterator precursorIter = precursors.iterator(); precursorIter.hasNext(); )
176             {
177                 Goal eachPrecursor = (Goal) precursorIter.next();
178 
179                 if ( !chain.contains( eachPrecursor ) )
180                 {
181                     stack.addLast( eachPrecursor );
182                 }
183             }
184 
185         }
186 
187         return (Goal[]) chain.toArray( Goal.EMPTY_ARRAY );
188     }
189 
190     /** Attempt to attain the specified goal.
191      *
192      *  @param name The name of the goal to attain.
193      *  @param session The context in which to attain goals.
194      *
195      *  @throws NoSuchGoalException if the <code>name</code> refers to no known goal.
196      *  @throws UnattainableGoalException if a precursor or the goal itself had an error.
197      *  @throws NoActionDefinitionException if a goal contains no action definition.
198      */
199     public void attainGoal( String name, Session session )
200         throws NoSuchGoalException, UnattainableGoalException, NoActionDefinitionException
201     {
202         Goal goal = getGoal( name );
203 
204         if ( goal == null )
205         {
206             throw new NoSuchGoalException( name );
207         }
208 
209         goal.attain( session );
210     }
211 
212     /** Attempt to percolate the specified goal.
213      *
214      *  @param name The name of the goal to percolate.
215      *  @param session The context in which to percolate goals.
216      *
217      *  @throws NoSuchGoalException if the <code>name</code> refers to no known goal.
218      *  @throws UnattainableGoalException if a postcursor or the goal itself had an error.
219      *  @throws NoActionDefinitionException if a goal contains no action definition.
220      */
221     public void percolateGoal( String name, Session session )
222         throws NoSuchGoalException, UnattainableGoalException, NoActionDefinitionException
223     {
224         Goal goal = getGoal( name );
225 
226         if ( goal == null )
227         {
228             throw new NoSuchGoalException( name );
229         }
230 
231         goal.percolate( session );
232     }
233 
234     /** Attempt to attain the specified goal.
235      *
236      *  @param name The name of the goal to attain.
237      *
238      *  @throws NoSuchGoalException if the <code>name</code> refers to no known goal.
239      *  @throws UnattainableGoalException if a precursor or the goal itself had an error.
240      *  @throws NoActionDefinitionException if a goal contains no action definition.
241      */
242     public void attainGoal( String name )
243         throws NoSuchGoalException, UnattainableGoalException, NoActionDefinitionException
244     {
245         attainGoal( name, new Session() );
246     }
247 
248     /** Attempt to percolate the specified goal.
249      *
250      *  @param name The name of the goal to percolate.
251      *
252      *  @throws NoSuchGoalException if the <code>name</code> refers to no known goal.
253      *  @throws UnattainableGoalException if a postcursor or the goal itself had an error.
254      *  @throws NoActionDefinitionException if a goal contains no action definition.
255      */
256     public void percolateGoal( String name )
257         throws NoSuchGoalException, UnattainableGoalException, NoActionDefinitionException
258     {
259         percolateGoal( name, new Session() );
260     }
261 
262     /** Add a <code>Goal</code> to this manager.
263      *
264      *  @param goal The <code>Goal</code> to add.
265      */
266     public void addGoal( Goal goal )
267     {
268         this.goals.put( goal.getName(), goal );
269     }
270 
271     /** Retrieve a <code>Goal</code> by name from this manager.
272      *
273      *  @param name The name of the goal to retrieve.
274      *
275      *  @return The <code>Goal</code> associated with the <code>name</code>,
276      *          or <code>null</code> if there is no such <code>Goal</code>.
277      */
278     public Goal getGoal( String name )
279     {
280         return (Goal) this.goals.get( name );
281     }
282 
283     /** Retrieve a <code>Goal</code> by name from this manager.
284      *
285      *  @param name The name of the goal to retrieve.
286      *  @param create Flag indicating if a new <code>Goal</code> should
287      *                be created and returned if none currently exists
288      *                bound to <code>name</code>.
289      *
290      *  @return The existing <code>Goal</code> associated with the <code>name</code>,
291      *          or a new <code>Goal</code> if none was previously associated with
292      *          <code>name</code>.
293      */
294     public Goal getGoal( String name, boolean create )
295     {
296         Goal goal = getGoal( name );
297 
298         if ( ( goal == null ) && create )
299         {
300             goal = new Goal( name );
301             addGoal( goal );
302         }
303 
304         return goal;
305     }
306 
307     /** Set the default goal name.
308      *
309      *  @param defaultGoalName The name of the default goal.
310      */
311     public void setDefaultGoalName( String defaultGoalName )
312     {
313         this.defaultGoalName = defaultGoalName;
314     }
315 
316     /** Retrieve the default goal name.
317      *
318      *  @return The namee of the default goal, or
319      *          <code>null</code> if not set.
320      */
321     public String getDefaultGoalName()
322     {
323         return this.defaultGoalName;
324     }
325 
326     /** Retrieve the default goal.
327      *
328      *  @return The default <code>Goal</code> or
329      *          <code>null</code> if a valid default
330      *          goal name has not been previously
331      *          specified using {@link #setDefaultGoalName}.
332      */
333     public Goal getDefaultGoal()
334     {
335         return getGoal( getDefaultGoalName() );
336     }
337 
338     /** Retrieve an unmodifiable collection of all <code>Goal</code>s 
339      *  that are a part of this <code>Project</code>.
340      *
341      *  @return An unmodifiable collection of all <code>Goal</code>s
342      *          that are members of this <code>Project</code>.
343      */
344     public Collection getGoals()
345     {
346         return Collections.unmodifiableCollection( this.goals.values() );
347     }
348 
349     /** Produce a textual representation suitable for debugging.
350      *
351      *  @return A textual representation suitable for debugging.
352      */
353     public String toString()
354     {
355         return "[Werkz: goals=" + this.goals + ";]";
356     }
357 
358     public void removeGoal( String name )
359     {
360         goals.remove( name );
361     }
362 }