1 | /*
|
---|
2 | * Copyright 2002-2005 The Apache Software Foundation
|
---|
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 | * Unless required by applicable law or agreed to in writing, software
|
---|
11 | * distributed under the License is distributed on an "AS IS" BASIS,
|
---|
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
---|
13 | * See the License for the specific language governing permissions and
|
---|
14 | * limitations under the License.
|
---|
15 | *
|
---|
16 | */
|
---|
17 |
|
---|
18 | package org.apache.tools.ant.taskdefs;
|
---|
19 |
|
---|
20 | import org.apache.tools.ant.BuildException;
|
---|
21 | import org.apache.tools.ant.ProjectHelper;
|
---|
22 | import org.apache.tools.ant.Project;
|
---|
23 | import org.apache.tools.ant.Task;
|
---|
24 | import org.apache.tools.ant.util.FileUtils;
|
---|
25 |
|
---|
26 | import java.io.File;
|
---|
27 | import java.util.Vector;
|
---|
28 |
|
---|
29 | /**
|
---|
30 | * <p>
|
---|
31 | * Task to import another build file into the current project.
|
---|
32 | * <p>
|
---|
33 | * It must be 'top level'. On execution it will read another Ant file
|
---|
34 | * into the same Project.
|
---|
35 | * <p>
|
---|
36 | * <b>Important</b>: we have not finalized how relative file references
|
---|
37 | * will be resolved in deep/complex build hierarchies -such as what happens
|
---|
38 | * when an imported file imports another file. Use absolute references for
|
---|
39 | * enhanced build file stability, especially in the imported files.
|
---|
40 | *
|
---|
41 | * Examples
|
---|
42 | * <pre>
|
---|
43 | * <import file="../common-targets.xml" />
|
---|
44 | * </pre>
|
---|
45 | * Import targets from a file in a parent directory.
|
---|
46 | *<p>
|
---|
47 | * <pre>
|
---|
48 | * <import file="${deploy-platform}.xml" />
|
---|
49 | * </pre>
|
---|
50 | * Import the project defined by the property deploy-platform
|
---|
51 | *
|
---|
52 | * @since Ant1.6
|
---|
53 | * @ant.task category="control"
|
---|
54 | */
|
---|
55 | public class ImportTask extends Task {
|
---|
56 | private String file;
|
---|
57 | private boolean optional;
|
---|
58 | private static final FileUtils FILE_UTILS = FileUtils.newFileUtils();
|
---|
59 |
|
---|
60 | /**
|
---|
61 | * sets the optional attribute
|
---|
62 | *
|
---|
63 | * @param optional if true ignore files that are not present,
|
---|
64 | * default is false
|
---|
65 | */
|
---|
66 | public void setOptional(boolean optional) {
|
---|
67 | this.optional = optional;
|
---|
68 | }
|
---|
69 |
|
---|
70 | /**
|
---|
71 | * the name of the file to import. How relative paths are resolved is still
|
---|
72 | * in flux: use absolute paths for safety.
|
---|
73 | * @param file the name of the file
|
---|
74 | */
|
---|
75 | public void setFile(String file) {
|
---|
76 | // I don't think we can use File - different rules
|
---|
77 | // for relative paths.
|
---|
78 | this.file = file;
|
---|
79 | }
|
---|
80 |
|
---|
81 | /**
|
---|
82 | * This relies on the task order model.
|
---|
83 | *
|
---|
84 | */
|
---|
85 | public void execute() {
|
---|
86 | if (file == null) {
|
---|
87 | throw new BuildException("import requires file attribute");
|
---|
88 | }
|
---|
89 | if (getOwningTarget() == null
|
---|
90 | || !"".equals(getOwningTarget().getName())) {
|
---|
91 | throw new BuildException("import only allowed as a top-level task");
|
---|
92 | }
|
---|
93 |
|
---|
94 | ProjectHelper helper =
|
---|
95 | (ProjectHelper) getProject().getReference("ant.projectHelper");
|
---|
96 | Vector importStack = helper.getImportStack();
|
---|
97 |
|
---|
98 | if (importStack.size() == 0) {
|
---|
99 | // this happens if ant is used with a project
|
---|
100 | // helper that doesn't set the import.
|
---|
101 | throw new BuildException("import requires support in ProjectHelper");
|
---|
102 | }
|
---|
103 |
|
---|
104 | if (getLocation() == null || getLocation().getFileName() == null) {
|
---|
105 | throw new BuildException("Unable to get location of import task");
|
---|
106 | }
|
---|
107 |
|
---|
108 | File buildFile = new File(getLocation().getFileName());
|
---|
109 | buildFile = new File(buildFile.getAbsolutePath());
|
---|
110 |
|
---|
111 | getProject().log("Importing file " + file + " from "
|
---|
112 | + buildFile.getAbsolutePath(), Project.MSG_VERBOSE);
|
---|
113 |
|
---|
114 | // Paths are relative to the build file they're imported from,
|
---|
115 | // *not* the current directory (same as entity includes).
|
---|
116 |
|
---|
117 | File buildFileParent = new File(buildFile.getParent());
|
---|
118 | File importedFile = FILE_UTILS.resolveFile(buildFileParent, file);
|
---|
119 |
|
---|
120 | if (!importedFile.exists()) {
|
---|
121 | String message =
|
---|
122 | "Cannot find " + file + " imported from "
|
---|
123 | + buildFile.getAbsolutePath();
|
---|
124 | if (optional) {
|
---|
125 | getProject().log(message, Project.MSG_VERBOSE);
|
---|
126 | return;
|
---|
127 | } else {
|
---|
128 | throw new BuildException(message);
|
---|
129 | }
|
---|
130 | }
|
---|
131 |
|
---|
132 | if (importStack.contains(importedFile)) {
|
---|
133 | getProject().log(
|
---|
134 | "Skipped already imported file:\n "
|
---|
135 | + importedFile + "\n", Project.MSG_VERBOSE);
|
---|
136 | return;
|
---|
137 | }
|
---|
138 |
|
---|
139 | try {
|
---|
140 | helper.parse(getProject(), importedFile);
|
---|
141 | } catch (BuildException ex) {
|
---|
142 | throw ProjectHelper.addLocationToBuildException(
|
---|
143 | ex, getLocation());
|
---|
144 | }
|
---|
145 | }
|
---|
146 |
|
---|
147 | }
|
---|