View Javadoc

1   /***
2    * Copyright 2007 the original author or authors.
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   * For more information visit
11   *         http://72miles.com and
12   *         http://architecturerules.googlecode.com/svn/docs/index.html
13   */
14  
15  package com.seventytwomiles.architecturerules.configuration;
16  
17  
18  import com.seventytwomiles.architecturerules.domain.JPackage;
19  import com.seventytwomiles.architecturerules.domain.Rule;
20  import com.seventytwomiles.architecturerules.domain.SourceDirectory;
21  import junit.framework.Assert;
22  import org.apache.commons.logging.Log;
23  import org.apache.commons.logging.LogFactory;
24  
25  import java.util.Collection;
26  import java.util.HashSet;
27  
28  
29  
30  /***
31   * <p>An instance of <code>Configuration</code> allows the application to
32   * specifiy where the source directories are, what rules to test against and
33   * under what conditions should an <code>Exception</code> be thrown.</p>
34   *
35   * <p>This <code>Configuration</code> may be loaded by configuration from an XML
36   * file in the classpath, through programmatic configuration, or both.</p>
37   *
38   * @author mikenereson
39   * @see ConfigurationFactory
40   * @see UnmodifiableConfiguration
41   */
42  public class Configuration {
43  
44  
45      protected static final Log log = LogFactory.getLog(Configuration.class);
46  
47      /***
48       * <p><code>Rules</code> that are read from the configuration file or added
49       * programatically.</p>
50       *
51       * @parameter rules Set
52       */
53      private final Collection<Rule> rules = new HashSet<Rule>();
54  
55      /***
56       * <p>List of <code>SourceDirectory</code> that are read from the
57       * configuration file and or added programatically.</p>
58       *
59       * @parameter sources List
60       */
61      private final Collection<SourceDirectory> sources
62              = new HashSet<SourceDirectory>();
63  
64      /***
65       * <p>sets to true when <samp>&lt;sources no-packages="exception"&gt;</samp>,
66       * false when <samp>&lt;sources no-packages="ignore"&gt;</samp></p>
67       *
68       * @parameter throwExceptionWhenNoPackages boolean
69       */
70      private boolean throwExceptionWhenNoPackages;
71  
72      /***
73       * <p>sets to true when <samp>&lt;cyclicalDependency test="true"/> </samp>,
74       * false when <samp>&lt;cyclicalDependency test="false"/> </samp></p>
75       *
76       * @parameter doCyclicDependencyTest boolean
77       */
78      private boolean doCyclicDependencyTest;
79  
80  
81      /***
82       * <p>Getter for property {@link #rules}.</p>
83       *
84       * @return Value for property <tt>rules</tt>.
85       */
86      public Collection<Rule> getRules() {
87          return this.rules;
88      }
89  
90  
91      /***
92       * <p>Getter for property {@link #sources}.</p>
93       *
94       * @return Value for property <tt>sources</tt>.
95       */
96      public Collection<SourceDirectory> getSources() {
97          return this.sources;
98      }
99  
100 
101     /***
102      * <p>Setter for property {@link #doCyclicDependencyTest}.</p>
103      *
104      * @param doCyclicDependencyTest Value to set for property
105      * <tt>doCyclicDependencyTest</tt>.
106      * @return Configuration this <code>Configuration</code> which allows for
107      *         method chaining
108      */
109     public Configuration setDoCyclicDependencyTest(
110             final boolean doCyclicDependencyTest) {
111 
112         this.doCyclicDependencyTest = doCyclicDependencyTest;
113 
114         return this;
115     }
116 
117 
118     /***
119      * <p>Setter for property {@link #throwExceptionWhenNoPackages}.</p>
120      *
121      * @param throwExceptionWhenNoPackages Value to set for property
122      * <tt>throwExceptionWhenNoPackages</tt>.
123      * @return Configuration this <code>Configuration</code> which allows for
124      *         method chaining
125      */
126     public Configuration setThrowExceptionWhenNoPackages(
127             final boolean throwExceptionWhenNoPackages) {
128 
129         this.throwExceptionWhenNoPackages = throwExceptionWhenNoPackages;
130 
131         return this;
132     }
133 
134 
135     /***
136      * <p>Add a new <code>Rule</code> to {@link #rules}</p>
137      *
138      * @param rule Rule to add
139      * @return Configuration this <code>Configuration</code> to allow for method
140      *         chaining.
141      */
142     public Configuration addRule(final Rule rule) {
143 
144         /* validate input */
145         Assert.assertNotNull("rule can not be null", rule);
146 
147         Assert.assertNotNull("rule id can not be null", rule.getId());
148 
149         final String id = rule.getId();
150         Assert.assertFalse("rule id must not be empty", id.equals(""));
151 
152         final Collection<JPackage> packages = rule.getPackages();
153         Assert.assertNotNull("rule packages can not be null", packages);
154 
155         Assert.assertFalse("rule packages must not be empty",
156                 rule.getPackages().isEmpty());
157 
158         Assert.assertFalse("rule violations must not be empty",
159                 rule.getViolations().isEmpty());
160 
161         final boolean added = rules.add(rule);
162 
163         if (added) {
164 
165             log.debug(String.format("added Rule %s to Configuration", id));
166 
167         } else {
168 
169             log.debug(String.format("failed to add Rule %s to Configuration",
170                     id));
171         }
172 
173         return this;
174     }
175 
176 
177     /***
178      * <p>Add a new <code>SourceDirectory</code> to {@link #sources}</p>
179      *
180      * @param sourceDirectory SourceDirectory to add
181      * @return Configuration this <code>Configuration</code> to allow for method
182      *         chaining.
183      */
184     public Configuration addSource(final SourceDirectory sourceDirectory) {
185 
186         if (sourceDirectory == null)
187             throw new IllegalArgumentException(
188                     "sourceDirectory can not be null");
189 
190         final String path = sourceDirectory.getPath();
191 
192         if (path == null || path.equals(""))
193             throw new IllegalArgumentException(
194                     "sourceDirectory.path can not be empty or null");
195 
196         final boolean added = sources.add(sourceDirectory);
197 
198         if (added) {
199 
200             log.debug(String.format("added source %s to Configuration", path));
201 
202         } else {
203 
204             log.debug(String.format("failed to add source %s to Configuration",
205                     path));
206         }
207 
208         return this;
209     }
210 
211 
212     /***
213      * <p>Getter for property {@link #doCyclicDependencyTest}.</p>
214      *
215      * @return Value for property <tt>doCyclicDependencyTest</tt>.
216      */
217     public boolean shouldDoCyclicDependencyTest() {
218         return doCyclicDependencyTest;
219     }
220 
221 
222     /***
223      * <p> Getter for property {@link #throwExceptionWhenNoPackages}.</p>
224      *
225      * @return Value for property <tt>throwExceptionWhenNoPackages</tt>.
226      */
227     public boolean shouldThrowExceptionWhenNoPackages() {
228         return throwExceptionWhenNoPackages;
229     }
230 }