001: /*
002: * GeoTools - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2005-2006, GeoTools Project Managment Committee (PMC)
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation;
009: * version 2.1 of the License.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: */
016: package org.geotools.referencing.factory.epsg;
017:
018: // J2SE dependencies
019: import java.io.BufferedReader;
020: import java.io.BufferedWriter;
021: import java.io.FileReader;
022: import java.io.FileWriter;
023: import java.io.IOException;
024: import java.util.regex.Matcher;
025: import java.util.regex.Pattern;
026:
027: /**
028: * Compacts {@code INSERT TO ...} SQL statements. This program doesn't need to be included
029: * in the Geotools JAR. It is run only once when a new SQL script is created. See
030: * <A HREF="doc-files/HSQL.html">Creating EPSG database for HSQL</A>.
031: *
032: * @since 2.2
033: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/plugin/epsg-hsql/src/main/java/org/geotools/referencing/factory/epsg/Compactor.java $
034: * @version $Id: Compactor.java 20432 2006-07-10 08:39:04Z jgarnett $
035: * @author Martin Desruisseaux
036: *
037: * @todo Find some way to exclude this file from JAR during Maven build.
038: */
039: final class Compactor {
040: /**
041: * No instantiation allowed.
042: */
043: private Compactor() {
044: }
045:
046: /**
047: * Run from the command line.
048: */
049: public static void main(final String[] args) throws IOException {
050: final BufferedReader in = new BufferedReader(new FileReader(
051: "EPSG.sql"));
052: final BufferedWriter out = new BufferedWriter(new FileWriter(
053: "EPSG-compact.sql"));
054: final String lineSeparator = System.getProperty(
055: "line.separator", "\n");
056: boolean insertDatum = false;
057: String insertStatement = null;
058: String line;
059: while ((line = in.readLine()) != null) {
060: if ((line = line.trim()).length() == 0) {
061: // Skip blank lines.
062: continue;
063: }
064: if (insertStatement != null) {
065: if (line.startsWith(insertStatement)) {
066: // The previous instruction was already an INSERT INTO the same table.
067: line = line.substring(insertStatement.length())
068: .trim();
069: line = removeUselessExponents(line);
070: if (insertDatum) {
071: line = removeRealizationEpochQuotes(line);
072: }
073: out.write(',');
074: out.write(lineSeparator);
075: out.write(line);
076: continue;
077: }
078: // Previous instruction was the last INSERT INTO for a given table.
079: // We now have a new instruction. Append the pending cariage return.
080: out.write(lineSeparator);
081: }
082: if (line.startsWith("INSERT INTO")) {
083: insertDatum = line
084: .startsWith("INSERT INTO EPSG_DATUM VALUES");
085: int values = line.indexOf("VALUES", 11);
086: if (values >= 0) {
087: // We are begining inserations in a new table.
088: values += 6; // Move to the end of "VALUES".
089: insertStatement = line.substring(0, values).trim();
090: line = line.substring(insertStatement.length())
091: .trim();
092: line = removeUselessExponents(line);
093: if (insertDatum) {
094: line = removeRealizationEpochQuotes(line);
095: }
096: out.write(insertStatement);
097: out.write(lineSeparator);
098: out.write(line);
099: continue;
100: }
101: }
102: insertStatement = null;
103: out.write(line);
104: out.write(lineSeparator);
105: }
106: out.close();
107: in.close();
108: }
109:
110: /**
111: * For private usage by the following method only.
112: */
113: private static final Pattern uselessExponentPattern = Pattern
114: .compile("([\\(\\,]\\-?\\d+\\.\\d+)E[\\+\\-]?0+([\\,\\)])");
115:
116: /**
117: * Removes the useless "E0" exponents after floating point numbers.
118: */
119: private static String removeUselessExponents(String line) {
120: StringBuffer cleaned = null;
121: final Matcher matcher = uselessExponentPattern.matcher(line);
122: while (true) {
123: int lastIndex = 0;
124: while (matcher.find()) {
125: // Make sure this is not a quoted text.
126: boolean quoted = false;
127: for (int i = matcher.start(); (i = line.lastIndexOf(
128: '\'', i - 1)) >= 0;) {
129: if (i == 0 || line.charAt(i - 1) != '\\') {
130: quoted = !quoted;
131: }
132: }
133: if (!quoted) {
134: // Found a number outside quotes. Replace.
135: if (cleaned == null) {
136: cleaned = new StringBuffer();
137: }
138: cleaned.append(line.substring(lastIndex, matcher
139: .end(1)));
140: lastIndex = matcher.end();
141: cleaned.append(line.substring(matcher.start(2),
142: lastIndex));
143: }
144: }
145: if (lastIndex == 0) {
146: return line;
147: }
148: cleaned.append(line.substring(lastIndex));
149: line = cleaned.toString();
150: matcher.reset(line);
151: cleaned.setLength(0);
152: }
153: }
154:
155: /**
156: * Remove the quotes in REALIZATION_EPOCH column (i.e. change the type
157: * from TEXT to INTEGER). This is the 5th column.
158: */
159: private static String removeRealizationEpochQuotes(final String line) {
160: int index = getIndexForColumn(line, 5);
161: if (line.charAt(index) != '\'') {
162: return line;
163: }
164: final StringBuffer cleaned = new StringBuffer(line.substring(0,
165: index));
166: if (line.charAt(++index) == '\'') {
167: cleaned.append("NULL");
168: } else
169: do {
170: cleaned.append(line.charAt(index));
171: } while (line.charAt(++index) != '\'');
172: cleaned.append(line.substring(index + 1));
173: return cleaned.toString();
174: }
175:
176: /**
177: * Returns the start index for the given column in the specified {@code VALUES} string.
178: * Column numbers start at 1.
179: */
180: private static int getIndexForColumn(final String line, int column) {
181: if (--column == 0) {
182: return 0;
183: }
184: boolean quote = false;
185: final int length = line.length();
186: for (int index = 0; index < length; index++) {
187: switch (line.charAt(index)) {
188: case '\'':
189: if (index == 0 || line.charAt(index - 1) != '\\')
190: quote = !quote;
191: break;
192: case ',':
193: if (!quote && --column == 0)
194: return index + 1;
195: break;
196: }
197: }
198: return length;
199: }
200: }
|