View Javadoc

1   /*
2    * #%L
3    * Native ARchive plugin for Maven
4    * %%
5    * Copyright (C) 2002 - 2014 NAR Maven Plugin developers.
6    * %%
7    * Licensed under the Apache License, Version 2.0 (the "License");
8    * you may not use this file except in compliance with the License.
9    * 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   * #L%
19   */
20  package com.github.maven_nar.cpptasks;
21  
22  import java.io.File;
23  import java.util.Enumeration;
24  import java.util.Vector;
25  
26  import org.apache.tools.ant.DirectoryScanner;
27  import org.apache.tools.ant.Project;
28  import org.apache.tools.ant.types.DataType;
29  
30  import com.github.maven_nar.cpptasks.types.ConditionalFileSet;
31  
32  /**
33   * An element that specifies a prototype file and rules for source files that
34   * should not use precompiled headers
35   *
36   * @author Curt Arnold
37   */
38  public final class PrecompileDef extends DataType {
39    private final Vector exceptSets = new Vector();
40    private String ifCond;
41    /**
42     * Directory of prototype file
43     */
44    private File prototype = new File("stdafx.cpp");
45    private String unlessCond;
46  
47    /**
48     * Constructor
49     * 
50     */
51    public PrecompileDef() {
52    }
53  
54    /**
55     * Method used by PrecompileExceptDef to add exception set to
56     * PrecompileDef.
57     */
58    public void appendExceptFileSet(final ConditionalFileSet exceptSet) {
59      exceptSet.setProject(getProject());
60      this.exceptSets.addElement(exceptSet);
61    }
62  
63    /**
64     * Adds filesets that specify files that should not be processed with
65     * precompiled headers enabled.
66     * 
67     */
68    public PrecompileExceptDef createExcept() {
69      return new PrecompileExceptDef(this);
70    }
71  
72    public void execute() throws org.apache.tools.ant.BuildException {
73      throw new org.apache.tools.ant.BuildException("Not an actual task, but looks like one for documentation purposes");
74    }
75  
76    public String[] getExceptFiles() {
77      final PrecompileDef ref = getRef();
78      if (ref != null) {
79        return ref.getExceptFiles();
80      }
81      if (this.exceptSets.size() == 0) {
82        return new String[0];
83      }
84      final Project p = getProject();
85      String[] exceptFiles = null;
86      final Enumeration setEnum = this.exceptSets.elements();
87      while (setEnum.hasMoreElements()) {
88        final ConditionalFileSet exceptSet = (ConditionalFileSet) setEnum.nextElement();
89        if (exceptSet.isActive()) {
90          final DirectoryScanner scanner = exceptSet.getDirectoryScanner(p);
91          final String[] scannerFiles = scanner.getIncludedFiles();
92          if (exceptFiles == null) {
93            exceptFiles = scannerFiles;
94          } else {
95            if (scannerFiles.length > 0) {
96              final String[] newFiles = new String[exceptFiles.length + scannerFiles.length];
97              System.arraycopy(exceptFiles, 0, newFiles, 0, exceptFiles.length);
98              int index = exceptFiles.length;
99              for (final String scannerFile : scannerFiles) {
100               newFiles[index++] = scannerFile;
101             }
102             exceptFiles = newFiles;
103           }
104         }
105       }
106     }
107     if (exceptFiles == null) {
108       exceptFiles = new String[0];
109     }
110     return exceptFiles;
111   }
112 
113   /**
114    * Gets prototype source file
115    * 
116    */
117   public File getPrototype() {
118     final PrecompileDef ref = getRef();
119     if (ref != null) {
120       return ref.getPrototype();
121     }
122     return this.prototype;
123   }
124 
125   private PrecompileDef getRef() {
126     if (isReference()) {
127       return (PrecompileDef) getCheckedRef(PrecompileDef.class, "PrecompileDef");
128     }
129     return null;
130   }
131 
132   public boolean isActive() {
133     final boolean isActive = CUtil.isActive(getProject(), this.ifCond, this.unlessCond);
134     if (!isActive) {
135       final PrecompileDef ref = getRef();
136       if (ref != null) {
137         return ref.isActive();
138       }
139     }
140     return isActive;
141   }
142 
143   /**
144    * Sets a description of the current data type.
145    */
146   @Override
147   public void setDescription(final String desc) {
148     super.setDescription(desc);
149   }
150 
151   /**
152    * Sets an id that can be used to reference this element.
153    * 
154    * @param id
155    *          id
156    */
157   public void setId(final String id) {
158     //
159     // this is actually accomplished by a different
160     // mechanism, but we can document it
161     //
162   }
163 
164   /**
165    * Set the 'if' condition.
166    * 
167    * The processor will be ignored unless the property is defined.
168    * 
169    * The value of property is insignificant, but values that would imply
170    * misinterpretation ("false", "no") will throw an exception when
171    * isActive() is evaluated.
172    * 
173    * @param propName
174    *          name of property
175    */
176   public void setIf(final String propName) {
177     this.ifCond = propName;
178   }
179 
180   /**
181    * Sets file to precompile.
182    * 
183    * Should be a source file that includes only one unguarded header file.
184    * Default value is "stdafx.cpp".
185    * 
186    * @param prototype
187    *          file path for prototype source file
188    */
189   public void setPrototype(final File prototype) {
190     if (isReference()) {
191       throw tooManyAttributes();
192     }
193     if (prototype == null) {
194       throw new NullPointerException("prototype");
195     }
196     this.prototype = prototype;
197   }
198 
199   /**
200    * Specifies that this element should behave as if the content of the
201    * element with the matching id attribute was inserted at this location.
202    * 
203    * @param ref
204    *          Reference to other element
205    * 
206    */
207   @Override
208   public void setRefid(final org.apache.tools.ant.types.Reference ref) {
209     super.setRefid(ref);
210   }
211 
212   /**
213    * Set the 'unless' condition. If named property exists at execution time,
214    * the processor will be ignored.
215    * 
216    * Value of property is insignificant, but values that would imply
217    * misinterpretation ("false", "no") of the behavior will throw an
218    * exception when isActive is called.
219    * 
220    * @param propName
221    *          name of property
222    */
223   public void setUnless(final String propName) {
224     this.unlessCond = propName;
225   }
226 }