001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: *
017: */
018:
019: package org.apache.tools.ant.taskdefs;
020:
021: import java.io.File;
022: import java.io.IOException;
023: import org.apache.tools.ant.BuildException;
024: import org.apache.tools.ant.Project;
025: import org.apache.tools.ant.taskdefs.condition.Os;
026: import org.apache.tools.ant.types.Commandline;
027: import org.apache.tools.ant.types.FileSet;
028: import org.apache.tools.ant.types.PatternSet;
029:
030: /**
031: * Chmod equivalent for unix-like environments.
032: *
033: * @since Ant 1.1
034: *
035: * @ant.task category="filesystem"
036: * @todo Refactor so it does not extend from ExecuteOn and then turn around
037: * and unsupport several attributes.
038: */
039: public class Chmod extends ExecuteOn {
040:
041: private FileSet defaultSet = new FileSet();
042: private boolean defaultSetDefined = false;
043: private boolean havePerm = false;
044:
045: /**
046: * Chmod task for setting file and directory permissions.
047: */
048: public Chmod() {
049: super .setExecutable("chmod");
050: super .setParallel(true);
051: super .setSkipEmptyFilesets(true);
052: }
053:
054: /**
055: * Set the project of this task.
056: * Calls the super class and sets the project on dhe default FileSet.
057: * @param project the project for this task.
058: * @see org.apache.tools.ant.ProjectComponent#setProject
059: */
060: public void setProject(Project project) {
061: super .setProject(project);
062: defaultSet.setProject(project);
063: }
064:
065: /**
066: * The file or single directory of which the permissions must be changed.
067: * @param src the source file or directory.
068: */
069: public void setFile(File src) {
070: FileSet fs = new FileSet();
071: fs.setFile(src);
072: addFileset(fs);
073: }
074:
075: /**
076: * The directory which holds the files whose permissions must be changed.
077: * @param src the directory.
078: */
079: public void setDir(File src) {
080: defaultSet.setDir(src);
081: }
082:
083: /**
084: * Set the new permissions.
085: * @param perm the new permissions.
086: */
087: public void setPerm(String perm) {
088: createArg().setValue(perm);
089: havePerm = true;
090: }
091:
092: /**
093: * Add a name entry on the include list.
094: * @return a NameEntry to be configured.
095: */
096: public PatternSet.NameEntry createInclude() {
097: defaultSetDefined = true;
098: return defaultSet.createInclude();
099: }
100:
101: /**
102: * Add a name entry on the exclude list.
103: * @return a nameentry to be configured.
104: */
105: public PatternSet.NameEntry createExclude() {
106: defaultSetDefined = true;
107: return defaultSet.createExclude();
108: }
109:
110: /**
111: * Add a set of patterns.
112: * @return a patternset to be configured.
113: */
114: public PatternSet createPatternSet() {
115: defaultSetDefined = true;
116: return defaultSet.createPatternSet();
117: }
118:
119: /**
120: * Sets the set of include patterns. Patterns may be separated by a comma
121: * or a space.
122: *
123: * @param includes the string containing the include patterns.
124: */
125: public void setIncludes(String includes) {
126: defaultSetDefined = true;
127: defaultSet.setIncludes(includes);
128: }
129:
130: /**
131: * Sets the set of exclude patterns. Patterns may be separated by a comma
132: * or a space.
133: *
134: * @param excludes the string containing the exclude patterns.
135: */
136: public void setExcludes(String excludes) {
137: defaultSetDefined = true;
138: defaultSet.setExcludes(excludes);
139: }
140:
141: /**
142: * Sets whether default exclusions should be used or not.
143: *
144: * @param useDefaultExcludes "true"|"on"|"yes" when default exclusions
145: * should be used, "false"|"off"|"no" when they
146: * shouldn't be used.
147: */
148: public void setDefaultexcludes(boolean useDefaultExcludes) {
149: defaultSetDefined = true;
150: defaultSet.setDefaultexcludes(useDefaultExcludes);
151: }
152:
153: /**
154: * Check the attributes and nested elements.
155: */
156: protected void checkConfiguration() {
157: if (!havePerm) {
158: throw new BuildException(
159: "Required attribute perm not set in chmod",
160: getLocation());
161: }
162:
163: if (defaultSetDefined
164: && defaultSet.getDir(getProject()) != null) {
165: addFileset(defaultSet);
166: }
167: super .checkConfiguration();
168: }
169:
170: /**
171: * Carry out the chmoding.
172: * @throws BuildException on error.
173: */
174: public void execute() throws BuildException {
175: /*
176: * In Ant 1.1, <chmod dir="foo" /> means, change the permissions
177: * of directory foo, not anything inside of it. This is the case the
178: * second branch of the if statement below catches for backwards
179: * compatibility.
180: */
181: if (defaultSetDefined
182: || defaultSet.getDir(getProject()) == null) {
183: try {
184: super .execute();
185: } finally {
186: if (defaultSetDefined
187: && defaultSet.getDir(getProject()) != null) {
188: filesets.removeElement(defaultSet);
189: }
190: }
191: } else if (isValidOs()) {
192: // we are chmodding the given directory
193: Execute execute = prepareExec();
194: Commandline cloned = (Commandline) cmdl.clone();
195: cloned.createArgument().setValue(
196: defaultSet.getDir(getProject()).getPath());
197: try {
198: execute.setCommandline(cloned.getCommandline());
199: runExecute(execute);
200: } catch (IOException e) {
201: throw new BuildException("Execute failed: " + e, e,
202: getLocation());
203: } finally {
204: // close the output file if required
205: logFlush();
206: }
207: }
208: }
209:
210: /**
211: * Set the executable.
212: * This is not allowed for Chmod.
213: * @param e ignored.
214: * @throws BuildException always.
215: * @ant.attribute ignore="true"
216: */
217: public void setExecutable(String e) {
218: throw new BuildException(getTaskType()
219: + " doesn\'t support the executable attribute",
220: getLocation());
221: }
222:
223: /**
224: * Set the command.
225: * This is not allowed for Chmod.
226: * @param cmdl ignored.
227: * @throws BuildException always.
228: * @ant.attribute ignore="true"
229: */
230: public void setCommand(Commandline cmdl) {
231: throw new BuildException(getTaskType()
232: + " doesn\'t support the command attribute",
233: getLocation());
234: }
235:
236: /**
237: * This is not allowed for Chmod.
238: * @param skip ignored.
239: * @throws BuildException always.
240: * @ant.attribute ignore="true"
241: */
242: public void setSkipEmptyFilesets(boolean skip) {
243: throw new BuildException(getTaskType()
244: + " doesn\'t support the skipemptyfileset attribute",
245: getLocation());
246: }
247:
248: /**
249: * This is not allowed for Chmod.
250: * @param b ignored.
251: * @throws BuildException always.
252: * @ant.attribute ignore="true"
253: */
254: public void setAddsourcefile(boolean b) {
255: throw new BuildException(getTaskType()
256: + " doesn\'t support the addsourcefile attribute",
257: getLocation());
258: }
259:
260: /**
261: * Check if the os is valid.
262: * Always include unix.
263: * @return true if the os is valid.
264: */
265: protected boolean isValidOs() {
266: return Os.isFamily(Os.FAMILY_UNIX) && super.isValidOs();
267: }
268: }
|