001    /*
002     * JBoss DNA (http://www.jboss.org/dna)
003     * See the COPYRIGHT.txt file distributed with this work for information
004     * regarding copyright ownership.  Some portions may be licensed
005     * to Red Hat, Inc. under one or more contributor license agreements.
006     * See the AUTHORS.txt file in the distribution for a full listing of 
007     * individual contributors. 
008     *
009     * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
010     * is licensed to you under the terms of the GNU Lesser General Public License as
011     * published by the Free Software Foundation; either version 2.1 of
012     * the License, or (at your option) any later version.
013     *
014     * JBoss DNA is distributed in the hope that it will be useful,
015     * but WITHOUT ANY WARRANTY; without even the implied warranty of
016     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
017     * Lesser General Public License for more details.
018     *
019     * You should have received a copy of the GNU Lesser General Public
020     * License along with this software; if not, write to the Free
021     * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
022     * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
023     */
024    package org.jboss.dna.maven;
025    
026    import java.util.EnumSet;
027    import java.util.LinkedHashSet;
028    import java.util.Set;
029    import org.jboss.dna.common.util.CheckArg;
030    
031    /**
032     * The cornerstone of Maven is its dependency list. Most every project depends upon others to build and run correctly, and if all
033     * Maven does for you is manage this list for you, you have gained a lot. Maven downloads and links the dependencies for you on
034     * compilation and other goals that require them. As an added bonus, Maven brings in the dependencies of those dependencies
035     * (transitive dependencies), allowing your list to focus solely on the dependencies your project requires.
036     * @author Randall Hauch
037     */
038    public class MavenDependency {
039    
040        /**
041         * The scope of the dependency - <code>compile</code>, <code>runtime</code>, <code>test</code>, <code>system</code>,
042         * and <code>provided</code>. Used to calculate the various classpaths used for compilation, testing, and so on. It also
043         * assists in determining which artifacts to include in a distribution of this project. For more information, see <a
044         * href="http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html">the dependency mechanism</a>.
045         */
046        public enum Scope {
047            COMPILE("compile"),
048            TEST("test"),
049            PROVIDED("provided"),
050            SYSTEM("system"),
051            RUNTIME("runtime");
052    
053            private String suffix;
054    
055            private Scope( String suffix ) {
056                this.suffix = suffix;
057            }
058    
059            public String getText() {
060                return this.suffix;
061            }
062    
063            public static Scope valueByText( String suffix, boolean useDefault ) {
064                for (Scope type : Scope.values()) {
065                    if (type.suffix.equalsIgnoreCase(suffix)) return type;
066                }
067                return useDefault ? getDefault() : null;
068            }
069    
070            public static Scope getDefault() {
071                return COMPILE;
072            }
073    
074            public static EnumSet<Scope> getRuntimeScopes() {
075                return EnumSet.of(COMPILE, RUNTIME);
076            }
077        }
078    
079        public static final String DEFAULT_TYPE = "jar";
080        public static final boolean DEFAULT_OPTIONAL = false;
081    
082        private MavenId id;
083        private String type = DEFAULT_TYPE;
084        private Scope scope = Scope.getDefault();
085        private String systemPath;
086        private boolean optional = DEFAULT_OPTIONAL;
087        private final Set<MavenId> exclusions = new LinkedHashSet<MavenId>();
088    
089        public MavenDependency( String coordinates ) {
090            this.id = new MavenId(coordinates);
091        }
092    
093        public MavenDependency( MavenId id ) {
094            CheckArg.isNotNull(id, "id");
095            this.id = id;
096        }
097    
098        public MavenDependency( String groupId, String artifactId, String version ) {
099            this.id = new MavenId(groupId, artifactId, version);
100        }
101    
102        public MavenDependency( String groupId, String artifactId, String version, String classifier ) {
103            this.id = new MavenId(groupId, artifactId, version, classifier);
104        }
105    
106        /**
107         * The identifier of the artifact for this dependency.
108         * @return the identifier
109         */
110        public MavenId getId() {
111            return this.id;
112        }
113    
114        /**
115         * The type of dependency. This defaults to <code>jar</code>. While it usually represents the extension on the filename of
116         * the dependency, that is not always the case. A type can be mapped to a different extension and a classifier. The type often
117         * correspongs to the packaging used, though this is also not always the case. Some examples are <code>jar</code>,
118         * <code>war</code>, <code>ejb-client</code> and <code>test-jar</code>. New types can be defined by plugins that set
119         * <code>extensions</code> to <code>true</code>, so this is not a complete list.
120         * @return the dependency type
121         */
122        public String getType() {
123            return this.type;
124        }
125    
126        /**
127         * Set the type of dependency.
128         * @param type the new dependency type. If null, then the type will be set to the
129         * {@link #DEFAULT_TYPE default dependency type}.
130         */
131        public void setType( String type ) {
132            this.type = type != null ? type.trim() : DEFAULT_TYPE;
133        }
134    
135        /**
136         * The scope of the dependency - <code>compile</code>, <code>runtime</code>, <code>test</code>, <code>system</code>,
137         * and <code>provided</code>. Used to calculate the various classpaths used for compilation, testing, and so on. It also
138         * assists in determining which artifacts to include in a distribution of this project. For more information, see <a
139         * href="http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html">the dependency mechanism</a>.
140         * @return the scope
141         */
142        public Scope getScope() {
143            return this.scope;
144        }
145    
146        /**
147         * @param scope Sets scope to the specified value.
148         */
149        public void setScope( Scope scope ) {
150            this.scope = scope != null ? scope : Scope.getDefault();
151        }
152    
153        public void setScope( String text ) {
154            this.scope = Scope.valueByText(text, true);
155        }
156    
157        /**
158         * FOR SYSTEM SCOPE ONLY. Note that use of this property is <b>discouraged</b> and may be replaced in later versions. This
159         * specifies the path on the filesystem for this dependency. Requires an absolute path for the value, not relative. Use a
160         * property that gives the machine specific absolute path, e.g. <code>${java.home}</code>.
161         * @return systemPath
162         */
163        public String getSystemPath() {
164            return this.systemPath;
165        }
166    
167        /**
168         * @param systemPath Sets systemPath to the specified value.
169         */
170        public void setSystemPath( String systemPath ) {
171            this.systemPath = systemPath != null ? systemPath.trim() : null;
172        }
173    
174        /**
175         * Indicates the dependency is optional for use of this library. While the version of the dependency will be taken into
176         * account for dependency calculation if the library is used elsewhere, it will not be passed on transitively.
177         * @return true if this is an optional dependency, or false otherwise
178         */
179        public boolean isOptional() {
180            return this.optional;
181        }
182    
183        /**
184         * @param optional Sets optional to the specified value.
185         */
186        public void setOptional( boolean optional ) {
187            this.optional = optional;
188        }
189    
190        /**
191         * Exclusions explicitly tell Maven that you don't want to include the specified project that is a dependency of this
192         * dependency (in other words, its transitive dependency). For example, the maven-embedder requires maven-core , and we do not
193         * wish to use it or its dependencies, then we would add it as an exclusion .
194         * @return the set of exclusions
195         */
196        public Set<MavenId> getExclusions() {
197            return this.exclusions;
198        }
199    
200        /**
201         * {@inheritDoc}
202         */
203        @Override
204        public int hashCode() {
205            return this.id.hashCode();
206        }
207    
208        /**
209         * {@inheritDoc}
210         */
211        @Override
212        public boolean equals( Object obj ) {
213            if (obj == this) return true;
214            if (obj instanceof MavenDependency) {
215                MavenDependency that = (MavenDependency)obj;
216                return this.id.equals(that.id);
217            }
218            return false;
219        }
220    
221        /**
222         * {@inheritDoc}
223         */
224        @Override
225        public String toString() {
226            return this.id.toString();
227        }
228    
229    }