View Javadoc
1   /*
2    * Copyright (c) 2011-2024 Qulice.com
3    *
4    * All rights reserved.
5    *
6    * Redistribution and use in source and binary forms, with or without
7    * modification, are permitted provided that the following conditions
8    * are met: 1) Redistributions of source code must retain the above
9    * copyright notice, this list of conditions and the following
10   * disclaimer. 2) Redistributions in binary form must reproduce the above
11   * copyright notice, this list of conditions and the following
12   * disclaimer in the documentation and/or other materials provided
13   * with the distribution. 3) Neither the name of the Qulice.com nor
14   * the names of its contributors may be used to endorse or promote
15   * products derived from this software without specific prior written
16   * permission.
17   *
18   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19   * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
20   * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
21   * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
22   * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
23   * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24   * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
27   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
29   * OF THE POSSIBILITY OF SUCH DAMAGE.
30   */
31  package com.qulice.ant;
32  
33  import com.jcabi.log.Logger;
34  import com.qulice.spi.Environment;
35  import java.io.File;
36  import java.net.MalformedURLException;
37  import java.net.URL;
38  import java.net.URLClassLoader;
39  import java.security.PrivilegedAction;
40  import java.util.Arrays;
41  import java.util.Collection;
42  import java.util.Collections;
43  import java.util.LinkedList;
44  import java.util.List;
45  import org.apache.commons.io.FileUtils;
46  import org.apache.commons.io.filefilter.DirectoryFileFilter;
47  import org.apache.commons.io.filefilter.IOFileFilter;
48  import org.apache.commons.io.filefilter.WildcardFileFilter;
49  
50  /**
51   * Environment, passed from ant task to validators.
52   * @since 0.13
53   */
54  public final class AntEnvironment implements Environment {
55  
56      /**
57       * Ant project.
58       */
59      private final AntProject project;
60  
61      /**
62       * Sources dirs.
63       */
64      private final AntPath sources;
65  
66      /**
67       * Classes dir (only one dir is supported).
68       */
69      private final File classes;
70  
71      /**
72       * Classpath dirs and files.
73       */
74      @SuppressWarnings("PMD.AvoidFieldNameMatchingMethodName")
75      private final AntPath classpath;
76  
77      /**
78       * Public ctor.
79       * @param prjct Ant project
80       * @param srcs Sources dirs
81       * @param clss Classes dir
82       * @param clsspth Classpath
83       * @checkstyle ParameterNumber (5 lines)
84       */
85      public AntEnvironment(
86          final AntProject prjct,
87          final AntPath srcs,
88          final File clss,
89          final AntPath clsspth) {
90          this.project = prjct;
91          this.sources = srcs;
92          this.classes = clss;
93          this.classpath = clsspth;
94      }
95  
96      @Override
97      public File basedir() {
98          return this.project.getBaseDir();
99      }
100 
101     @Override
102     public File tempdir() {
103         return new File(this.basedir(), "temp");
104     }
105 
106     @Override
107     public File outdir() {
108         return this.classes;
109     }
110 
111     @Override
112     public String param(final String name, final String value) {
113         String property = this.project.getProperty(name);
114         if (property == null) {
115             property = value;
116         }
117         return property;
118     }
119 
120     @Override
121     @SuppressWarnings("PMD.AvoidInstantiatingObjectsInLoops")
122     public ClassLoader classloader() {
123         final List<URL> urls = new LinkedList<>();
124         try {
125             for (final String path : this.classpath()) {
126                 urls.add(
127                     new File(path).toURI().toURL()
128                 );
129             }
130             urls.add(this.classes.toURI().toURL());
131         } catch (final MalformedURLException ex) {
132             throw new IllegalStateException("Failed to build URL", ex);
133         }
134         final URLClassLoader loader =
135             new AntEnvironment.PrivilegedClassLoader(urls).run();
136         for (final URL url : loader.getURLs()) {
137             Logger.debug(this, "Classpath: %s", url);
138         }
139         return loader;
140     }
141 
142     @Override
143     public Collection<String> classpath() {
144         return Arrays.asList(this.classpath.list());
145     }
146 
147     @Override
148     @SuppressWarnings("PMD.AvoidInstantiatingObjectsInLoops")
149     public Collection<File> files(final String pattern) {
150         final Collection<File> files = new LinkedList<>();
151         final IOFileFilter filter = new WildcardFileFilter(pattern);
152         for (final String dir : this.sources.list()) {
153             final File source = new File(dir);
154             if (source.exists() && source.isDirectory()) {
155                 files.addAll(
156                     FileUtils.listFiles(
157                         source,
158                         filter,
159                         DirectoryFileFilter.INSTANCE
160                     )
161                 );
162             }
163         }
164         return files;
165     }
166 
167     @Override
168     // @todo #337 Implement exclude and excludes for ant QuliceTask
169     public boolean exclude(final String check, final String name) {
170         return false;
171     }
172 
173     @Override
174     public Collection<String> excludes(final String checker) {
175         return Collections.emptyList();
176     }
177 
178     /**
179      * Creates URL ClassLoader in privileged block.
180      *
181      * @since 0.1
182      */
183     private static final class PrivilegedClassLoader implements
184         PrivilegedAction<URLClassLoader> {
185         /**
186          * URLs for class loading.
187          */
188         private final List<URL> urls;
189 
190         /**
191          * Constructor.
192          * @param urls URLs for class loading.
193          */
194         private PrivilegedClassLoader(final List<URL> urls) {
195             this.urls = urls;
196         }
197 
198         @Override
199         public URLClassLoader run() {
200             return new URLClassLoader(
201                 this.urls.toArray(new URL[this.urls.size()]),
202                 Thread.currentThread().getContextClassLoader()
203             );
204         }
205     }
206 }