001: /*
002:
003: Derby - Class org.apache.derbyBuild.propertyconfig
004:
005: Licensed to the Apache Software Foundation (ASF) under one or more
006: contributor license agreements. See the NOTICE file distributed with
007: this work for additional information regarding copyright ownership.
008: The ASF licenses this file to You under the Apache License, Version 2.0
009: (the "License"); you may not use this file except in compliance with
010: the License. You may obtain a copy of the License at
011:
012: http://www.apache.org/licenses/LICENSE-2.0
013:
014: Unless required by applicable law or agreed to in writing, software
015: distributed under the License is distributed on an "AS IS" BASIS,
016: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: See the License for the specific language governing permissions and
018: limitations under the License.
019:
020: */
021:
022: package org.apache.derbyBuild;
023:
024: import java.util.Properties;
025: import java.io.FileInputStream;
026: import java.io.FileOutputStream;
027: import java.io.IOException;
028: import java.io.File;
029:
030: import java.util.StringTokenizer;
031: import java.util.Properties;
032: import java.util.Enumeration;
033:
034: /**
035: *
036: * Usage:
037: * java propertyConfig <master file> <config> <output file>
038: * <B> e.g., java propertyConfig dbms.properties cloudsync
039: * cloudsync.dbms.properties
040: *
041: * <P>
042: * This program takes a master property file, and using the configuration
043: * specification, generate an output file that only contains the properties
044: * for that particular configuration.
045: *
046: * <P>
047: * For the different types of legitamite configurations, please see
048: * org.apache.derby.modules.properties
049: *
050: * <P>
051: * PropertySplitter will look at cloudscape.config.<tag> to see which
052: * configuration a particular module belongs to.
053: * <B>E.g., cloudscape.config.dataComm.listen=cloudtarget,cloudsync
054: * <B>this means all properties associated with dataComm.listen will be
055: * in the output properties file only if we are generating for the cloudsync or
056: * cloudtarget configuration. They will not be in the output properties file
057: * if we are generating for the cloud or cloudscape configuration.
058: *
059: */
060:
061: public class propertyconfig {
062:
063: public static String header = "######## This is a generated file, do not edit.\n"
064: + "#\n# This file is generated as by propertyConfig\n"
065: + "#\n";
066:
067: public static String footer = "\n######## This is a generated file, do not edit.\n";
068:
069: public static void main(String[] args) throws IOException {
070: if (args.length != 3)
071: printUsageAndExit();
072:
073: File masterfile = new File(args[0]);
074: File outputfile = new File(args[2]);
075:
076: if (!masterfile.exists())
077: printUsageAndExit();
078:
079: // OK, got the input cleared up, now do the processing
080: Properties masterProp = new Properties();
081: FileInputStream is = new FileInputStream(masterfile);
082:
083: try {
084: masterProp.load(is);
085: } finally {
086: if (is != null)
087: is.close();
088: }
089:
090: process(masterProp, args[1], outputfile);
091: }
092:
093: /**
094: * For each module with a particular tag in derby.module.<tag>, see if
095: * there is any configuration restriction. If there is no
096: * cloudscape.config.<tag> property, then this module should be present in
097: * all configurations. If there is a cloudscape.config.<tag>, then this
098: * module should only be present in the configurations listed.
099: *
100: * <br>If this module should be present or this configuration, then gather
101: * up all the properties belong to this module and send it to the output
102: * file.
103: *
104: */
105: private static void process(Properties moduleList, String config,
106: File outputfile) throws IOException {
107: Properties outputProp = new Properties();
108:
109: // copy this code from
110: // org.apache.derby.impl.services.monitor.BaseMonitor
111: //
112: for (Enumeration e = moduleList.propertyNames(); e
113: .hasMoreElements();) {
114: String key = (String) e.nextElement();
115: if (key.startsWith("derby.module.")) {
116: String tag = key.substring("derby.module.".length());
117:
118: // Check to see if it has any configuration requirements
119: String configKey = "cloudscape.config.".concat(tag);
120: String configProp = moduleList.getProperty(configKey);
121:
122: boolean match = false;
123:
124: if (configProp != null) {
125: StringTokenizer st = new StringTokenizer(
126: configProp, ",");
127: while (st.hasMoreTokens()) {
128:
129: String s = st.nextToken().trim();
130:
131: // if config spec says all, it should not have other
132: // configurations
133: if (s.equalsIgnoreCase("all")
134: && !configProp.trim().equals("all")) {
135: System.out
136: .println("illegal config specification "
137: + key);
138: System.exit(3);
139: }
140:
141: // if config spec says none, it should not have other
142: // configurations
143: if (s.equalsIgnoreCase("none")
144: && !configProp.trim().equals("none")) {
145: System.out
146: .println("illegal config specification "
147: + key);
148: System.exit(4);
149: }
150:
151: if (s.equalsIgnoreCase(config)
152: || s.equalsIgnoreCase("all")) {
153: match = true;
154: break;
155: }
156: }
157: } else {
158: // no config property, this module goes to all configs
159: System.out.println("Need config specification for "
160: + key);
161: System.exit(2);
162: }
163:
164: if (match) {
165: // gather up all relavant properties and put it in
166: // outputProp
167:
168: // derby.module.<tag>
169: outputProp.put(key, moduleList.getProperty(key));
170:
171: // don't output cloudscape.config.<tag>
172: // that line only has meaning to this program
173:
174: // derby.env.classes.<tag>
175: String envKey = "derby.env.classes.".concat(tag);
176: if (moduleList.getProperty(envKey) != null)
177: outputProp.put(envKey, moduleList
178: .getProperty(envKey));
179:
180: // derby.env.jdk.<tag>
181: //
182: // some of the configs only support one java env. Some modules
183: // have alternate implementation for running on java1 and
184: // java2 platforms. If we get rid of, say, the java2
185: // implementation, then the monitor won't load the java1
186: // implementation if that module specifies that it should
187: // only be loaded in a java1 environment. The result is
188: // that some critical modules will be missing and the
189: // database won't boot.
190: //
191: // the convention is, for modules that have both java1 and
192: // java2 implementation, they must named the module as
193: // derby.env.jdk.<name>J1 or
194: // derby.env.jdk.<name>J2
195: // in other words, the <tag> must end with J1 or J2.
196: //
197: // If a config only use one of the two implementation, then
198: // this program will not put the one env.jdk line to the
199: // output properties. As a result, this one implementation
200: // will be loaded when run in any environment.
201: //
202: // This does not apply to any module that only has one
203: // implementation that runs on a specific jdk environment.
204: //
205: //derby.env.jdk.<tag>
206: envKey = "derby.env.jdk.".concat(tag);
207:
208: if (moduleList.getProperty(envKey) != null) {
209: // by default keep the jdk env specification with the
210: // config
211: boolean saveEnvKey = true;
212:
213: // figure out if this is a tag of the form <name>J1 or
214: // <name>J2.
215: if (tag.endsWith("J1") || tag.endsWith("J2")) {
216: // ok, this is a module with alternate
217: // implementation for java 1 and java 2. If this
218: // config ditches one of them, then do not output
219: // the env line
220: int length = tag.length() - 2;
221: String alternateTag = tag.substring(0,
222: length);
223:
224: if (tag.endsWith("J1"))
225: alternateTag += "J2";
226: else
227: alternateTag += "J1";
228:
229: // see if
230: // 1) this module has an alternate impl for the
231: // other jdk and
232: // 2) this config is not going to pick it up.
233: //
234:
235: String alternateImplKey = "derby.module."
236: + alternateTag;
237: String alternateJDKEnv = "derby.env.jdk."
238: + alternateTag;
239: String alternateImplConfigKey = "cloudscape.config."
240: + alternateTag;
241:
242: // if any of of these are not present, then we
243: // don't have a problem because either there is no
244: // alternate implementation, or the alternate
245: // implementation is not based on jdk, or the
246: // alternate jdk based implemenation will also be
247: // present in this configuration
248:
249: if ((moduleList
250: .getProperty(alternateImplKey) != null)
251: && (moduleList
252: .getProperty(alternateJDKEnv) != null)
253: && (moduleList
254: .getProperty(alternateImplConfigKey) != null)) {
255: // there is an alternate impl that is jdk based
256: // and it has a config tag. Let's see if it is
257: // part of this config.
258: String alternateConfigProp = moduleList
259: .getProperty(alternateImplConfigKey);
260:
261: // we know that there are
262: // derby.module.<tag>J2 and
263: // derby.module.<tag>J1 and
264: // derby.env.jdk.<tag>J2 and
265: // derby.env.jdk.<tag>J1 and
266: // cloudscape.config.<tag>J2 and
267: // cloudscape.config.<tag>J1
268: StringTokenizer st2 = new StringTokenizer(
269: alternateConfigProp, ",");
270:
271: boolean ok = false;
272: while (st2.hasMoreTokens()) {
273: String s = st2.nextToken().trim();
274:
275: if (s.equalsIgnoreCase(config)
276: || s
277: .equalsIgnoreCase("all")) {
278: ok = true;
279: break;
280: }
281: }
282: // the alternate module impl is not part of
283: // this config, do not save the jdk env key
284: if (!ok)
285: saveEnvKey = false;
286: }
287: }
288:
289: if (saveEnvKey)
290: outputProp.put(envKey, moduleList
291: .getProperty(envKey));
292: }
293:
294: // NOTE, if other types of properties are added to
295: // modules.properties, be sure to add it here too.
296: }
297: }
298: }
299:
300: FileOutputStream os = new FileOutputStream(outputfile);
301: try {
302: outputProp.save(os, header.concat("# config is ").concat(
303: config).concat(footer));
304: } finally {
305: if (os != null)
306: os.close();
307: }
308: }
309:
310: private static void printUsageAndExit() {
311: StringBuffer buf = new StringBuffer(400);
312:
313: buf
314: .append(
315: "Usage propertyConfig <masterFile> <config> <outputFile>\n")
316: .append(
317: "masterFile must be a pre-existing properties file ")
318: .append("containing all the modules properites\n")
319: .append("config must be a configuration defined in ")
320: .append("org.apache.derby.modules.properties.\n")
321: .append(
322: "outputFile must not be a pre-existing properties file.\n\n")
323: .append(
324: "propertyConfig will generate the outputFile based on")
325: .append(
326: "the masterfile and the configuration specified.")
327: .append(
328: "\n\nE.g., java propertyConfig dbms.properties cloudsync dbms.cloudsync.properties\n");
329:
330: System.out.println(buf.toString());
331: System.exit(1);
332: }
333: }
|