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: package org.apache.ivy.ant;
019:
020: import java.io.File;
021: import java.io.IOException;
022: import java.io.InputStream;
023: import java.net.MalformedURLException;
024: import java.net.URL;
025: import java.text.ParseException;
026: import java.util.Arrays;
027: import java.util.Collection;
028: import java.util.Properties;
029:
030: import org.apache.ivy.Ivy;
031: import org.apache.ivy.core.settings.IvySettings;
032: import org.apache.ivy.core.settings.IvyVariableContainer;
033: import org.apache.ivy.util.Message;
034: import org.apache.ivy.util.url.CredentialsStore;
035: import org.apache.ivy.util.url.URLHandler;
036: import org.apache.ivy.util.url.URLHandlerDispatcher;
037: import org.apache.ivy.util.url.URLHandlerRegistry;
038: import org.apache.tools.ant.BuildException;
039: import org.apache.tools.ant.Project;
040: import org.apache.tools.ant.Task;
041: import org.apache.tools.ant.taskdefs.Property;
042:
043: public class IvyAntSettings extends Task {
044:
045: public static class Credentials {
046: private String realm;
047:
048: private String host;
049:
050: private String username;
051:
052: private String passwd;
053:
054: public String getPasswd() {
055: return this .passwd;
056: }
057:
058: public void setPasswd(String passwd) {
059: this .passwd = passwd;
060: }
061:
062: public String getRealm() {
063: return this .realm;
064: }
065:
066: public void setRealm(String realm) {
067: this .realm = format(realm);
068: }
069:
070: public String getHost() {
071: return this .host;
072: }
073:
074: public void setHost(String host) {
075: this .host = format(host);
076: }
077:
078: public String getUsername() {
079: return this .username;
080: }
081:
082: public void setUsername(String userName) {
083: this .username = format(userName);
084: }
085: }
086:
087: /**
088: * Use to override a previous definition of settings with the same id
089: */
090: public static final String OVERRIDE_TRUE = "true";
091: /**
092: * Use to avoid overriding a previous definition of settings with the same id
093: */
094: public static final String OVERRIDE_FALSE = "false";
095: /**
096: * Use to raise an error if attempting to override a previous definition of settings with the
097: * same id
098: */
099: public static final String OVERRIDE_NOT_ALLOWED = "notallowed";
100:
101: private static final Collection OVERRIDE_VALUES = Arrays
102: .asList(new String[] { OVERRIDE_TRUE, OVERRIDE_FALSE,
103: OVERRIDE_NOT_ALLOWED });
104:
105: private Ivy ivyEngine = null;
106:
107: private File file = null;
108:
109: private URL url = null;
110:
111: private String realm = null;
112:
113: private String host = null;
114:
115: private String userName = null;
116:
117: private String passwd = null;
118:
119: private String id = "ivy.instance";
120:
121: private String override = OVERRIDE_NOT_ALLOWED;
122:
123: /**
124: * Returns the default ivy settings of this classloader. If it doesn't exist yet, a new one is
125: * created using the given project to back the VariableContainer.
126: *
127: * @param project TODO add text.
128: * @return An IvySetting instance.
129: */
130: public static IvyAntSettings getDefaultInstance(Project project) {
131: Object defaultInstanceObj = project
132: .getReference("ivy.instance");
133: if (defaultInstanceObj != null
134: && defaultInstanceObj.getClass().getClassLoader() != IvyAntSettings.class
135: .getClassLoader()) {
136: project
137: .log(
138: "ivy.instance reference an ivy:settings defined in an other classloader. "
139: + "An new default one will be used in this project.",
140: Project.MSG_WARN);
141: defaultInstanceObj = null;
142: }
143: if (defaultInstanceObj != null
144: && !(defaultInstanceObj instanceof IvyAntSettings)) {
145: throw new BuildException(
146: "ivy.instance reference a "
147: + defaultInstanceObj.getClass().getName()
148: + " an not an IvyAntSettings. Please don't use this reference id ()");
149: }
150: if (defaultInstanceObj == null) {
151: project.log(
152: "No ivy:settings found for the default reference 'ivy.instance'. "
153: + "A default instance will be used",
154: Project.MSG_INFO);
155: IvyAntSettings defaultInstance = new IvyAntSettings();
156: defaultInstance.setProject(project);
157: defaultInstance.perform();
158: return defaultInstance;
159: } else {
160: return (IvyAntSettings) defaultInstanceObj;
161: }
162: }
163:
164: public File getFile() {
165: return file;
166: }
167:
168: public URL getUrl() {
169: return url;
170: }
171:
172: public String getPasswd() {
173: return passwd;
174: }
175:
176: public void setPasswd(String aPasswd) {
177: passwd = aPasswd;
178: }
179:
180: public String getRealm() {
181: return realm;
182: }
183:
184: public void setRealm(String aRealm) {
185: realm = format(aRealm);
186: }
187:
188: public String getHost() {
189: return host;
190: }
191:
192: public void setHost(String aHost) {
193: host = format(aHost);
194: }
195:
196: public String getUsername() {
197: return userName;
198: }
199:
200: public void setUsername(String aUserName) {
201: userName = format(aUserName);
202: }
203:
204: private static String format(String str) {
205: return str == null ? str : (str.trim().length() == 0 ? null
206: : str.trim());
207: }
208:
209: public void addConfiguredCredentials(Credentials c) {
210: CredentialsStore.INSTANCE.addCredentials(c.getRealm(), c
211: .getHost(), c.getUsername(), c.getPasswd());
212: }
213:
214: public void setFile(File file) {
215: this .file = file;
216: }
217:
218: public void setUrl(String confUrl) throws MalformedURLException {
219: this .url = new URL(confUrl);
220: }
221:
222: public void setOverride(String override) {
223: if (!OVERRIDE_VALUES.contains(override)) {
224: throw new IllegalArgumentException(
225: "invalid override value '" + override + "'. "
226: + "Valid values are " + OVERRIDE_VALUES);
227: }
228: this .override = override;
229: }
230:
231: /*
232: * This is usually not necessary to define a reference in Ant, but it's the only
233: * way to know the id of the settings, which we use to set ant properties.
234: */
235: public void setId(String id) {
236: this .id = id;
237: }
238:
239: public String getId() {
240: return id;
241: }
242:
243: /*
244: * public void execute() throws BuildException {
245: * ensureMessageInitialised();
246: * if (getId()==null) {
247: * log("No id specified for the ivy:settings, set the instance as the default one",
248: * Project.MSG_DEBUG); getProject().addReference("ivy.instance", this); } else {
249: * getProject().addReference(id, this); } }
250: */
251:
252: /**
253: * Return the configured Ivy instance.
254: * @return Returns the configured Ivy instance.
255: */
256: public Ivy getConfiguredIvyInstance() {
257: if (ivyEngine == null) {
258: perform();
259: }
260: return ivyEngine;
261: }
262:
263: public void execute() throws BuildException {
264: if (!OVERRIDE_TRUE.equals(override)) {
265: if (getProject().getReference(id) != null) {
266: if (OVERRIDE_FALSE.equals(override)) {
267: verbose("a settings definition is already available for "
268: + id + ": skipping");
269: return;
270: } else {
271: // OVERRIDE_NOT_ALLOWED
272: throw new BuildException(
273: "overriding a previous definition of ivy:settings with the id '"
274: + id
275: + "'"
276: + " is not allowed when using override='"
277: + OVERRIDE_NOT_ALLOWED + "'.");
278: }
279: }
280: }
281: getProject().addReference(id, this );
282: Property prop = new Property() {
283: public void execute() throws BuildException {
284: addProperties(getDefaultProperties());
285: }
286: };
287: prop.setProject(getProject());
288: prop.execute();
289: createIvyEngine();
290: }
291:
292: private void createIvyEngine() {
293: IvyAntVariableContainer ivyAntVariableContainer = new IvyAntVariableContainer(
294: getProject());
295:
296: IvySettings settings = new IvySettings(ivyAntVariableContainer);
297:
298: if (file == null && url == null) {
299: defineDefaultSettingFile(ivyAntVariableContainer);
300: }
301:
302: Ivy ivy = Ivy.newInstance(settings);
303: ivy.getLoggerEngine().pushLogger(new AntMessageLogger(this ));
304: Message.showInfo();
305: try {
306: configureURLHandler();
307: if (file != null) {
308: if (!file.exists()) {
309: throw new BuildException(
310: "settings file does not exist: " + file);
311: }
312: ivy.configure(file);
313: } else {
314: if (url == null) {
315: throw new AssertionError(
316: "ivy setting should have either a file, either an url,"
317: + " and if not defineDefaultSettingFile must set it.");
318: }
319: ivy.configure(url);
320: }
321: ivyAntVariableContainer.updateProject(id);
322: ivyEngine = ivy;
323: } catch (ParseException e) {
324: throw new BuildException(
325: "impossible to configure ivy:settings with given "
326: + (file != null ? "file: " + file : "url :"
327: + url) + " :" + e, e);
328: } catch (IOException e) {
329: throw new BuildException(
330: "impossible to configure ivy:settings with given "
331: + (file != null ? "file: " + file : "url :"
332: + url) + " :" + e, e);
333: } finally {
334: ivy.getLoggerEngine().popLogger();
335: }
336: }
337:
338: protected Properties getDefaultProperties() {
339: URL url = IvySettings.getDefaultPropertiesURL();
340: // this is copy of loadURL code from ant Property task (not available in 1.5.1)
341: Properties props = new Properties();
342: verbose("Loading " + url);
343: try {
344: InputStream is = url.openStream();
345: try {
346: props.load(is);
347: } finally {
348: if (is != null) {
349: is.close();
350: }
351: }
352: } catch (IOException ex) {
353: throw new BuildException(ex);
354: }
355: return props;
356: }
357:
358: /**
359: * Set file or url to its default value
360: *
361: * @param variableContainer
362: */
363: private void defineDefaultSettingFile(
364: IvyVariableContainer variableContainer) {
365: String settingsFileName = variableContainer
366: .getVariable("ivy.conf.file");
367: if (settingsFileName != null
368: && !settingsFileName.equals(variableContainer
369: .getVariable("ivy.settings.file"))) {
370: info("DEPRECATED: 'ivy.conf.file' is deprecated, use 'ivy.settings.file' instead");
371: } else {
372: settingsFileName = variableContainer
373: .getVariable("ivy.settings.file");
374: }
375: File[] settingsLocations = new File[] {
376: new File(getProject().getBaseDir(), settingsFileName),
377: new File(getProject().getBaseDir(), "ivyconf.xml"),
378: new File(settingsFileName), new File("ivyconf.xml") };
379: for (int i = 0; i < settingsLocations.length; i++) {
380: file = settingsLocations[i];
381: verbose("searching settings file: trying " + file);
382: if (file.exists()) {
383: break;
384: }
385: }
386: if (!file.exists()) {
387: if (Boolean.valueOf(
388: getProject().getProperty("ivy.14.compatible"))
389: .booleanValue()) {
390: info("no settings file found, using Ivy 1.4 default...");
391: file = null;
392: url = IvySettings.getDefault14SettingsURL();
393: } else {
394: info("no settings file found, using default...");
395: file = null;
396: url = IvySettings.getDefaultSettingsURL();
397: }
398: }
399: }
400:
401: private void verbose(String msg) {
402: log(msg, Project.MSG_VERBOSE);
403: }
404:
405: private void info(String msg) {
406: log(msg, Project.MSG_INFO);
407: }
408:
409: private void warn(String msg) {
410: log(msg, Project.MSG_WARN);
411: }
412:
413: private void configureURLHandler() {
414: // TODO : the credentialStore should also be scoped
415: CredentialsStore.INSTANCE.addCredentials(getRealm(), getHost(),
416: getUsername(), getPasswd());
417:
418: URLHandlerDispatcher dispatcher = new URLHandlerDispatcher();
419: URLHandler httpHandler = URLHandlerRegistry.getHttp();
420: dispatcher.setDownloader("http", httpHandler);
421: dispatcher.setDownloader("https", httpHandler);
422: URLHandlerRegistry.setDefault(dispatcher);
423: }
424:
425: }
|