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