001: /*
002: * $Id: HostnameTask.java,v 1.22 2007/05/21 15:11:32 agoubard Exp $
003: *
004: * Copyright 2003-2007 Orange Nederland Breedband B.V.
005: * See the COPYRIGHT file for redistribution and use restrictions.
006: */
007: package org.xins.common.ant;
008:
009: import java.io.InputStream;
010:
011: import org.apache.tools.ant.BuildException;
012: import org.apache.tools.ant.Project;
013: import org.apache.tools.ant.Task;
014:
015: import org.xins.common.net.IPAddressUtils;
016:
017: /**
018: * Apache Ant task that determines the host name.
019: *
020: * @version $Revision: 1.22 $ $Date: 2007/05/21 15:11:32 $
021: * @author <a href="mailto:ernst@ernstdehaan.com">Ernst de Haan</a>
022: *
023: * @since XINS 1.0.0
024: */
025: public class HostnameTask extends Task {
026:
027: /**
028: * Default name for the property to set.
029: */
030: public static final String DEFAULT_PROPERTY_NAME = "hostname";
031:
032: /**
033: * Name of the property to store the host name in. Default is
034: * {@link #DEFAULT_PROPERTY_NAME}.
035: */
036: private String _propertyName = DEFAULT_PROPERTY_NAME;
037:
038: /**
039: * Sets the name of the property. If <code>null</code> or <code>""</code>
040: * is passed as the argument, then {@link #DEFAULT_PROPERTY_NAME} is
041: * assumed.
042: *
043: * @param newPropertyName
044: * the name of the property to store the host name in, or
045: * <code>null</code> if the {@link #DEFAULT_PROPERTY_NAME} should be
046: * assumed.
047: */
048: public void setProperty(String newPropertyName) {
049: if (newPropertyName == null) {
050: _propertyName = DEFAULT_PROPERTY_NAME;
051: } else {
052: newPropertyName = newPropertyName.trim();
053: if ("".equals(newPropertyName)) {
054: _propertyName = DEFAULT_PROPERTY_NAME;
055: } else {
056: _propertyName = newPropertyName;
057: }
058: }
059: }
060:
061: /**
062: * Called by the project to let the task do its work.
063: *
064: * @throws BuildException
065: * if something goes wrong with the build.
066: */
067: public void execute() throws BuildException {
068:
069: // Do not override the property value
070: if (getProject().getUserProperty(_propertyName) != null) {
071: String logMessage = "Override ignored for property \""
072: + _propertyName + "\".";
073: log(logMessage, Project.MSG_VERBOSE);
074: return;
075: }
076:
077: // First try using the IPAddressUtils class from the JDK
078: String hostname = IPAddressUtils.getLocalHost();
079:
080: // Normalize the host name and filter out fakes (empty or "localhost")
081: if (hostname != null) {
082: hostname = hostname.trim();
083: if ("".equals(hostname) || "localhost".equals(hostname)) {
084: hostname = null;
085: }
086: }
087:
088: // No hostname yet? Try running the 'hostname' command on POSIX systems
089: if (hostname == null) {
090: hostname = runHostnameCommand();
091: }
092:
093: // Still no hostname, fallback to a default and then log a warning
094: if (hostname == null) {
095: hostname = "localhost";
096:
097: String message = "Determining hostname of localhost failed. "
098: + "Setting property to \"" + hostname + "\".";
099: log(message, Project.MSG_WARN);
100: }
101:
102: // Actually set the property
103: getProject().setUserProperty(_propertyName, hostname);
104: }
105:
106: /**
107: * Tries running the POSIX <code>hostname</code> command to determine the
108: * name of the local host. If this does not succeed, then <code>null</code>
109: * is returned instead of the hostname.
110: *
111: * @return
112: * the name of the local host, or <code>null</code>.
113: */
114: private String runHostnameCommand() {
115:
116: final String CMD = "hostname";
117:
118: String hostname;
119: try {
120: Process process = Runtime.getRuntime().exec(CMD);
121: process.waitFor();
122:
123: int exitValue = process.exitValue();
124: if (exitValue != 0) {
125: String message = "Executing command \"" + CMD
126: + "\" failed with exit code " + exitValue + '.';
127: log(message, Project.MSG_VERBOSE);
128: return null;
129: }
130:
131: // Get the stdout output from the process
132: InputStream in = process.getInputStream();
133:
134: // Configure max expected hostname length
135: int maxHostNameLength = 500;
136:
137: // Read the whole output
138: byte[] bytes = new byte[maxHostNameLength];
139: int read = in.read(bytes);
140: if (read < 0) {
141: return null;
142: }
143:
144: // Convert the bytes to a String
145: final String ENCODING = "US-ASCII";
146: hostname = new String(bytes, 0, read, ENCODING);
147:
148: // Check all characters in the hostname
149: for (int i = 0; i < read; i++) {
150: char ch = hostname.charAt(i);
151: if (ch >= 'a' && ch <= 'z') {
152: // OK: fall through
153: } else if (ch > 'A' && ch <= 'Z') {
154: // OK: fall through
155: } else if (ch > '0' && ch <= '9') {
156: // OK: fall through
157: } else if (ch == '-' || ch == '_' || ch == '.') {
158: // OK: fall through
159: } else if (ch == '\n' || ch == '\r') {
160: hostname = hostname.substring(0, i);
161: i = read;
162: } else {
163: String message = "Found invalid character "
164: + (int) ch + " in output of command \""
165: + CMD + "\".";
166: log(message, Project.MSG_VERBOSE);
167: return null;
168: }
169: }
170:
171: } catch (Exception exception) {
172: String message = "Caught unexpected "
173: + exception.getClass().getName()
174: + " while attempting to execute command \"" + CMD
175: + "\".";
176: log(message, Project.MSG_VERBOSE);
177: hostname = null;
178: }
179:
180: if (hostname != null) {
181: hostname = hostname.trim();
182: if (hostname.length() < 1) {
183: hostname = null;
184: }
185: }
186:
187: return hostname;
188: }
189: }
|