001: /*
002: * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright notice. All rights reserved.
003: */
004: package com.tc.config.schema.setup;
005:
006: import org.apache.commons.cli.CommandLine;
007: import org.apache.commons.cli.Option;
008: import org.apache.commons.cli.Options;
009: import org.apache.commons.cli.ParseException;
010: import org.apache.commons.cli.PosixParser;
011: import org.apache.commons.lang.StringUtils;
012:
013: import com.tc.config.schema.IllegalConfigurationChangeHandler;
014: import com.tc.logging.TCLogger;
015:
016: import java.io.File;
017: import java.net.InetAddress;
018: import java.net.UnknownHostException;
019:
020: /**
021: * The standard implementation of {@link com.tc.config.schema.setup.TVSConfigurationSetupManagerFactory} — uses
022: * system properties and command-line arguments to create the relevant factories.
023: */
024: public class StandardTVSConfigurationSetupManagerFactory extends
025: BaseTVSConfigurationSetupManagerFactory {
026:
027: private static final String CONFIG_SPEC_ARGUMENT_NAME = "config";
028: /**
029: * <code>public</code> for <strong>TESTS AND DOCUMENTATION ONLY</strong>.
030: */
031: public static final String CONFIG_SPEC_ARGUMENT_WORD = "--"
032: + CONFIG_SPEC_ARGUMENT_NAME;
033: public static final String SERVER_NAME_ARGUMENT_WORD = "-n";
034:
035: private static final String L2_NAME_PROPERTY_NAME = "tc.server.name";
036: public static final String DEFAULT_CONFIG_SPEC = "tc-config.xml";
037: public static final String DEFAULT_CONFIG_PATH = "default-config.xml";
038: public static final String DEFAULT_CONFIG_URI = "resource:///"
039: + StandardTVSConfigurationSetupManagerFactory.class
040: .getPackage().getName().replace('.', '/') + "/"
041: + DEFAULT_CONFIG_PATH;
042:
043: private final String defaultL2Identifier;
044: private final String configSpec;
045: private final File cwd;
046:
047: public StandardTVSConfigurationSetupManagerFactory(boolean isForL2,
048: IllegalConfigurationChangeHandler illegalChangeHandler)
049: throws ConfigurationSetupException {
050: this ((String[]) null, isForL2, illegalChangeHandler);
051: }
052:
053: public StandardTVSConfigurationSetupManagerFactory(String[] args,
054: boolean isForL2,
055: IllegalConfigurationChangeHandler illegalChangeHandler)
056: throws ConfigurationSetupException {
057: this (parseDefaultCommandLine(args, isForL2), isForL2,
058: illegalChangeHandler);
059: }
060:
061: private static CommandLine parseDefaultCommandLine(String[] args,
062: boolean isForL2) throws ConfigurationSetupException {
063: try {
064: if (args == null || args.length == 0) {
065: return new PosixParser().parse(new Options(),
066: new String[0]);
067: } else {
068: Options options = createOptions(isForL2);
069:
070: return new PosixParser().parse(options, args);
071: }
072: } catch (ParseException pe) {
073: throw new ConfigurationSetupException(pe
074: .getLocalizedMessage(), pe);
075: }
076: }
077:
078: public StandardTVSConfigurationSetupManagerFactory(
079: CommandLine commandLine, boolean isForL2,
080: IllegalConfigurationChangeHandler illegalChangeHandler)
081: throws ConfigurationSetupException {
082: super (illegalChangeHandler);
083:
084: String configFileOnCommandLine = null;
085: String l2NameOnCommandLine = null;
086:
087: configFileOnCommandLine = StringUtils.trimToNull(commandLine
088: .getOptionValue('f'));
089: l2NameOnCommandLine = StringUtils.trimToNull(commandLine
090: .getOptionValue('n'));
091:
092: String effectiveConfigSpec;
093: effectiveConfigSpec = StringUtils
094: .trimToNull(configFileOnCommandLine != null ? configFileOnCommandLine
095: : System
096: .getProperty(TVSConfigurationSetupManagerFactory.CONFIG_FILE_PROPERTY_NAME));
097: String specifiedL2Identifier = StringUtils
098: .trimToNull(l2NameOnCommandLine != null ? l2NameOnCommandLine
099: : System.getProperty(L2_NAME_PROPERTY_NAME));
100:
101: if (StringUtils.isBlank(effectiveConfigSpec)) {
102: File localConfig = new File(System.getProperty("user.dir"),
103: DEFAULT_CONFIG_SPEC);
104:
105: if (localConfig.exists()) {
106: effectiveConfigSpec = localConfig.getAbsolutePath();
107: } else if (isForL2) {
108: effectiveConfigSpec = DEFAULT_CONFIG_URI;
109: }
110: }
111: this .configSpec = effectiveConfigSpec;
112:
113: if (StringUtils.isBlank(this .configSpec)) {
114: // formatting
115: throw new ConfigurationSetupException(
116: "You must specify the location of the Terracotta "
117: + "configuration file for this process, using the "
118: + "'" + CONFIG_FILE_PROPERTY_NAME
119: + "' system property.");
120: }
121:
122: String cwdAsString = System.getProperty("user.dir");
123: if (StringUtils.isBlank(cwdAsString)) {
124: // formatting
125: throw new ConfigurationSetupException(
126: "We can't find the working directory of the process; we need this to continue. "
127: + "(The system property 'user.dir' was "
128: + (cwdAsString == null ? "null" : "'"
129: + cwdAsString + "'") + ".)");
130: }
131:
132: this .cwd = new File(cwdAsString);
133:
134: if (specifiedL2Identifier != null) {
135: this .defaultL2Identifier = specifiedL2Identifier;
136: } else {
137: String hostName = null;
138:
139: try {
140: hostName = InetAddress.getLocalHost().getHostName();
141: } catch (UnknownHostException uhe) {
142: /**/
143: }
144:
145: String potentialName = hostName;
146:
147: if (potentialName != null
148: && potentialName.indexOf(".") >= 0)
149: potentialName = potentialName.substring(0,
150: potentialName.indexOf("."));
151: if (potentialName != null)
152: potentialName = potentialName.trim();
153:
154: if (!StringUtils.isBlank(potentialName)
155: && (!potentialName.equalsIgnoreCase("localhost"))) {
156: this .defaultL2Identifier = potentialName;
157: } else {
158: this .defaultL2Identifier = null;
159: }
160: }
161: }
162:
163: public static Options createOptions(boolean isForL2) {
164: Options options = new Options();
165:
166: Option configFileOption = new Option("f",
167: CONFIG_SPEC_ARGUMENT_NAME, true,
168: "the configuration file to use, specified as a file path or URL");
169: configFileOption.setArgName("file-or-URL");
170: configFileOption.setType(String.class);
171:
172: if (isForL2) {
173: configFileOption.setRequired(false);
174: options.addOption(configFileOption);
175:
176: Option l2NameOption = new Option("n", "name", true,
177: "the name of this L2; defaults to the host name");
178: l2NameOption.setRequired(false);
179: l2NameOption.setArgName("l2-name");
180: options.addOption(l2NameOption);
181: } else {
182: configFileOption.setRequired(true);
183: options.addOption(configFileOption);
184: }
185:
186: return options;
187: }
188:
189: public L1TVSConfigurationSetupManager createL1TVSConfigurationSetupManager(
190: TCLogger logger) throws ConfigurationSetupException {
191: ConfigurationCreator configurationCreator = new StandardXMLFileConfigurationCreator(
192: logger, this .configSpec, this .cwd, this .beanFactory);
193:
194: L1TVSConfigurationSetupManager setupManager = new StandardL1TVSConfigurationSetupManager(
195: configurationCreator, this .defaultValueProvider,
196: this .xmlObjectComparator, this .illegalChangeHandler);
197:
198: return setupManager;
199: }
200:
201: public L1TVSConfigurationSetupManager createL1TVSConfigurationSetupManager()
202: throws ConfigurationSetupException {
203: ConfigurationCreator configurationCreator = new StandardXMLFileConfigurationCreator(
204: this .configSpec, this .cwd, this .beanFactory);
205:
206: L1TVSConfigurationSetupManager setupManager = new StandardL1TVSConfigurationSetupManager(
207: configurationCreator, this .defaultValueProvider,
208: this .xmlObjectComparator, this .illegalChangeHandler);
209:
210: return setupManager;
211: }
212:
213: public L2TVSConfigurationSetupManager createL2TVSConfigurationSetupManager(
214: String l2Name) throws ConfigurationSetupException {
215: if (l2Name == null)
216: l2Name = this .defaultL2Identifier;
217:
218: ConfigurationCreator configurationCreator;
219: configurationCreator = new StandardXMLFileConfigurationCreator(
220: this .configSpec, this .cwd, this .beanFactory);
221:
222: return new StandardL2TVSConfigurationSetupManager(
223: configurationCreator, l2Name,
224: this.defaultValueProvider, this.xmlObjectComparator,
225: this.illegalChangeHandler);
226: }
227:
228: }
|