001: /*
002: * Copyright 2006-2007, Unitils.org
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package org.unitils.dbmaintainer.structure.impl;
017:
018: import org.unitils.core.UnitilsException;
019: import org.unitils.core.dbsupport.DbSupport;
020: import org.unitils.dbmaintainer.structure.DataSetStructureGenerator;
021: import org.unitils.dbmaintainer.util.BaseDatabaseTask;
022: import static org.unitils.thirdparty.org.apache.commons.io.IOUtils.closeQuietly;
023: import org.unitils.util.PropertyUtils;
024:
025: import java.io.BufferedWriter;
026: import java.io.File;
027: import java.io.FileWriter;
028: import java.io.Writer;
029: import java.util.Properties;
030: import java.util.Set;
031:
032: /**
033: * Implementation of {@link DataSetStructureGenerator} that generates xml schema files for data sets.
034: * <p/>
035: * This will generate an xsd for each configured database schema. Each database schema will be described in an xsd named
036: * 'schema_name'.xsd. A general dataset.xsd will also be generated. This xsd refers to the database schema specific xsds.
037: *
038: * @author Tim Ducheyne
039: * @author Filip Neven
040: */
041: public class XsdDataSetStructureGenerator extends BaseDatabaseTask
042: implements DataSetStructureGenerator {
043:
044: /* Property key for the target directory for the generated xsd files */
045: public static final String PROPKEY_XSD_DIR_NAME = "dataSetStructureGenerator.xsd.dirName";
046:
047: /* Property key for the suffix to use when defining complex types for the table definitions */
048: public static final String PROPKEY_XSD_COMPLEX_TYPE_SUFFIX = "dataSetStructureGenerator.xsd.complexTypeSuffix";
049:
050: /* The target directory for the xsd files */
051: private String xsdDirectoryName;
052:
053: /* The suffix to use when defining complex types for the table definitions */
054: private String complexTypeSuffix;
055:
056: /**
057: * Initializes the generator.
058: *
059: * @param configuration The config, not null
060: */
061: @Override
062: protected void doInit(Properties configuration) {
063: xsdDirectoryName = PropertyUtils.getString(
064: PROPKEY_XSD_DIR_NAME, configuration);
065: complexTypeSuffix = PropertyUtils.getString(
066: PROPKEY_XSD_COMPLEX_TYPE_SUFFIX, configuration);
067: }
068:
069: /**
070: * Generates the XSDs, and writes them to the target directory specified by the property {@link #PROPKEY_XSD_DIR_NAME}.
071: */
072: public void generateDataSetStructure() {
073: File xsdDirectory = new File(xsdDirectoryName);
074: xsdDirectory.mkdirs();
075:
076: generateDataSetXsd(xsdDirectory);
077: for (DbSupport dbSupport : dbSupports) {
078: generateDatabaseSchemaXsd(dbSupport, xsdDirectory);
079: }
080: }
081:
082: /**
083: * Generates a general dataset xsd that will refer to database schema specific dataset XSDs.
084: *
085: * @param xsdDirectory The target directory, not null
086: */
087: protected void generateDataSetXsd(File xsdDirectory) {
088: Writer writer = null;
089: try {
090: writer = new BufferedWriter(new FileWriter(new File(
091: xsdDirectory, "dataset.xsd")));
092:
093: String defaultSchemaName = defaultDbSupport.getSchemaName();
094: writer
095: .write("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n");
096: writer
097: .write("<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" elementFormDefault=\"qualified\" xmlns:dflt=\""
098: + defaultSchemaName + "\">\n");
099:
100: for (DbSupport dbSupport : dbSupports) {
101: String schemaName = dbSupport.getSchemaName();
102: writer.write("\t<xsd:import namespace=\"" + schemaName
103: + "\" schemaLocation=\"" + schemaName
104: + ".xsd\" />\n");
105: }
106:
107: writer.write("\t<xsd:element name=\"dataset\">\n");
108: writer.write("\t\t<xsd:complexType>\n");
109: writer
110: .write("\t\t\t<xsd:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n");
111:
112: Set<String> defaultSchemaTableNames = defaultDbSupport
113: .getTableNames();
114: for (String tableName : defaultSchemaTableNames) {
115: writer.write("\t\t\t\t<xsd:element name=\"" + tableName
116: + "\" type=\"dflt:" + tableName
117: + complexTypeSuffix + "\" />\n");
118: }
119: writer.write("\t\t\t\t<xsd:any namespace=\""
120: + defaultSchemaName + "\" />\n");
121:
122: writer.write("\t\t\t</xsd:choice>\n");
123: writer.write("\t\t</xsd:complexType>\n");
124: writer.write("\t</xsd:element>\n");
125: writer.write("</xsd:schema>\n");
126:
127: } catch (Exception e) {
128: throw new UnitilsException("Error generating xsd file: "
129: + xsdDirectory, e);
130: } finally {
131: closeQuietly(writer);
132: }
133: }
134:
135: /**
136: * Generates an XSD for the database schema of the given db support.
137: *
138: * @param dbSupport The db support, not null
139: * @param xsdDirectory The target directory, not null
140: */
141: protected void generateDatabaseSchemaXsd(DbSupport dbSupport,
142: File xsdDirectory) {
143: Writer writer = null;
144: try {
145: writer = new BufferedWriter(new FileWriter(new File(
146: xsdDirectory, dbSupport.getSchemaName() + ".xsd")));
147:
148: writer
149: .write("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n");
150: writer
151: .write("<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" elementFormDefault=\"qualified\" xmlns=\""
152: + dbSupport.getSchemaName()
153: + "\" targetNamespace=\""
154: + dbSupport.getSchemaName() + "\">\n");
155:
156: Set<String> tableNames = dbSupport.getTableNames();
157: for (String tableName : tableNames) {
158: writer.write("\t<xsd:element name=\"" + tableName
159: + "\" type=\"" + tableName + complexTypeSuffix
160: + "\" />\n");
161: }
162:
163: for (String tableName : tableNames) {
164: writer.write("\t<xsd:complexType name=\"" + tableName
165: + complexTypeSuffix + "\">\n");
166:
167: Set<String> columnNames = dbSupport
168: .getColumnNames(tableName);
169: for (String columnName : columnNames) {
170: writer.write("\t\t<xsd:attribute name=\""
171: + columnName + "\" use=\"optional\" />\n");
172: }
173: writer.write("\t</xsd:complexType>\n");
174: }
175: writer.write("</xsd:schema>\n");
176:
177: } catch (Exception e) {
178: throw new UnitilsException("Error generating xsd file: "
179: + xsdDirectory, e);
180: } finally {
181: closeQuietly(writer);
182: }
183: }
184:
185: }
|