001: /**
002: * Objective Database Abstraction Layer (ODAL)
003: * Copyright (c) 2004, The ODAL Development Group
004: * All rights reserved.
005: * For definition of the ODAL Development Group please refer to LICENCE.txt file
006: *
007: * Distributable under LGPL license.
008: * See terms of license at gnu.org.
009: */package com.completex.objective.tools;
010:
011: import java.io.*;
012: import java.util.LinkedHashMap;
013: import java.util.Map;
014: import java.util.Iterator;
015:
016: /**
017: * @author Gennady Krizhevsky
018: */
019: public class XhtmlConterter {
020:
021: public static final String debug_path1 = "doc/guides/dev/debug1-odal-guide.xhtml";
022: public static final String debug_path2 = "doc/guides/dev/debug2-odal-guide.xhtml";
023: public static final String debug_path3 = "doc/guides/dev/debug3-odal-guide.xhtml";
024: public static final String debug_path4 = "doc/guides/dev/debug4-odal-guide.xhtml";
025: public static final String debug_path5 = "doc/guides/dev/debug5-odal-guide.xhtml";
026: public static final String err_path = "doc/guides/dev/err-odal-guide.xhtml";
027:
028: public static final String in_path = "doc/guides/dev/odal-guide.xhtml";
029:
030: public static final String out_path = "doc/guides/html/odal-guide.xhtml";
031:
032: public static final String ANCOR_START_REAL = "#";
033: public static final String ANCOR_START = ".//";
034: public static final String ANCOR_START_PATTERN = "\\.//";
035: public static final String ANCOR_END = "|outline";
036: public static final String ANCOR_END_PATTERN = "\\|outline";
037: public static final String REF_PREFIX = "a name=\"";
038: public static final String QUESTION_MARK_PATTERN = "\\?";
039: public static final String QUESTION_MARK_ENCODED = "_3F";
040: private static final String IMG = "img";
041: private static final String DQ = "\"";
042: private static final String SRC = "src=";
043: public static final String XMLDOC = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
044: public static final String XHTML_TO_REPLACE = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">";
045: public static final String XML_IE_XSL = "<?xml-stylesheet type=\"text/xsl\" href=\"copy.xsl\"?>";
046: public static final String XHTML_IE_DOCTYPE = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n"
047: + " \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">";
048: public static final String XHTML_META = "<meta";
049: public static final String XHTML_BASE = "<base";
050:
051: public static final String TITLE = "<title>Objective database abstraction layer (ODAL) - User Guide</title>\n"
052: + " <meta name=\"verify-v1\" content=\"x7RV+e9F26NkZdSOU5/tHI4mWcrUU0c7x7UdUh8ou3s=\" />\n"
053: + " <meta name=\"author\" content=\"Gennady Krizhevsky\"/>\n"
054: + "\t<meta name=\"copyright\" content=\"Copyright (c) 2007 by Gennady Krizhevsky\"/>\n"
055: + " <meta name=\"ROBOTS\" content=\"INDEX,FOLLOW\"/>\n"
056: + " <meta name=\"Googlebot\" content=\"all\"/>\n"
057: + " <meta name=\"Description\" CONTENT=\"Objective database abstraction layer (ODAL) is a high-performance multi-purpose database manipulation framework. Features include query API, O-R mapping, data validation/conversion, stored procedure support, code generation.\"/>\n"
058: + " <meta name=\"Keywords\" content=\"odal, object relational mapping, database, java, persistence, mapper, persistency, object, objective, abstraction layer, framework, code generation, generating\"/>\n";
059: private static final boolean DEBUG = false;
060:
061: public static void main(String[] args) throws IOException {
062: XhtmlConterter xhtmlConterter = new XhtmlConterter();
063: xhtmlConterter.process();
064: }
065:
066: private void process() throws IOException {
067: String doc = readFileAsString();
068: doc = doc.replaceAll("\\s+" + ANCOR_END_PATTERN,
069: ANCOR_END_PATTERN);
070: ReplaceCollection replaceCollection = extractReplaces(doc);
071: doc = replace(doc, replaceCollection);
072: write(doc);
073: }
074:
075: private void write(String doc) throws IOException {
076: String out_path = XhtmlConterter.out_path;
077: write(out_path, doc);
078: }
079:
080: private void write(String out_path, String doc) throws IOException {
081: File file = new File(out_path);
082: getParentDirName(file);
083: FileWriter fileWriter = new FileWriter(file);
084: BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
085: bufferedWriter.write(doc);
086: bufferedWriter.flush();
087: bufferedWriter.close();
088: }
089:
090: private String getParentDirName(File file) {
091: String parentDirName = file.getParent();
092: File dir = new File(parentDirName);
093: if (!dir.exists()) {
094: throw new IllegalArgumentException("Directory "
095: + parentDirName + " does not exist");
096: }
097: return parentDirName;
098: }
099:
100: private String replace(String doc,
101: ReplaceCollection replaceCollection) {
102: writeSilently(debug_path1, doc);
103: Map replaces = replaceCollection.getReplaces();
104: doc = replaceAncorStarts(doc);
105: writeSilently(debug_path2, doc);
106: doc = replaceRefs(replaces, doc);
107: doc = replaceImgs(doc);
108: doc = insertIeRelated(doc);
109: doc = insertIeRelated2(doc);
110: doc = removeMetaIeRelated(doc);
111: doc = insertTitleAndMeta(doc);
112: return doc;
113: }
114:
115: private String removeMetaIeRelated(String doc) {
116: StringBuffer buffer = new StringBuffer(doc);
117: int start = doc.indexOf(XHTML_META);
118: int end = doc.indexOf(XHTML_BASE);
119: buffer.delete(start, end);
120: return buffer.toString();
121: }
122:
123: private String insertTitleAndMeta(String doc) {
124: StringBuffer buffer = new StringBuffer(doc);
125: int start = doc.indexOf(XHTML_BASE);
126: buffer.insert(start, TITLE);
127: return buffer.toString();
128: }
129:
130: private String insertIeRelated(String doc) {
131: StringBuffer buffer = new StringBuffer(doc);
132: buffer.insert(XMLDOC.length(), XML_IE_XSL);
133: return buffer.toString();
134: }
135:
136: private String insertIeRelated2(String doc) {
137: StringBuffer buffer = new StringBuffer(doc);
138: int start = XMLDOC.length() + XML_IE_XSL.length();
139: buffer.delete(start, start + XHTML_TO_REPLACE.length());
140: buffer.insert(start, XHTML_IE_DOCTYPE);
141: return buffer.toString();
142: }
143:
144: private String replaceImgs(String doc) {
145: File[] files = getImgFiles();
146: for (int i = 0; i < files.length; i++) {
147: File file = files[i];
148: System.out.println("File = " + file);
149: }
150:
151: int existingImgIndex = doc.indexOf(IMG);
152: String src = SRC + DQ;
153: int existingImgIndexStart = doc.indexOf(src,
154: existingImgIndex + 1);
155: int existingImgIndexEnd = doc.indexOf(DQ, existingImgIndexStart
156: + src.length() + 1);
157: String existingImgString = doc.substring(existingImgIndexStart,
158: existingImgIndexEnd + 1);
159:
160: int nextIndex = -1;
161: int diff = 0;
162: int count = 0;
163: while ((nextIndex = doc.indexOf(existingImgString, nextIndex
164: + existingImgString.length() + diff + 1)) >= 0) {
165: String replacementString = SRC + DQ + IMG + "/"
166: + files[count].getName() + DQ;
167: int replacementStringLength = replacementString.length();
168: diff = replacementStringLength - existingImgString.length();
169: System.out.println("existingImgString = "
170: + existingImgString + "; replacementString = "
171: + replacementString);
172: doc = doc
173: .replaceFirst(existingImgString, replacementString);
174: count++;
175: }
176:
177: return doc;
178: }
179:
180: private File[] getImgFiles() {
181: String parentDirName = getParentDirName(new File(out_path));
182:
183: String imgDirName = parentDirName + "/img";
184:
185: File imgDir = new File(imgDirName);
186:
187: FilenameFilter filter = new FilenameFilter() {
188: public boolean accept(File dir, String name) {
189: return name != null && name.startsWith("pic");
190: }
191: };
192: return imgDir.listFiles(filter);
193: }
194:
195: private String replaceRefs(Map replaces, String doc) {
196: writeSilently(debug_path3, doc);
197: for (Iterator it = replaces.keySet().iterator(); it.hasNext();) {
198: String realNameOfRef = (String) it.next();
199: String nameOfRef = (String) replaces.get(realNameOfRef);
200: String prefixedNameOfRef = prefixedNameOfRef(nameOfRef);
201: String replacement = REF_PREFIX + realNameOfRef;
202: int pos = doc.indexOf(prefixedNameOfRef);
203: printReplacemant(prefixedNameOfRef, replacement, pos);
204: String newDoc = doc.replaceAll(prefixedNameOfRef,
205: replacement);
206: if (newDoc.equals(doc)) {
207: writeSilently(err_path, doc);
208: throw new IllegalArgumentException(
209: "nothing replaced with replacement = "
210: + replacement + "; "
211: + "prefixedNameOfRef = ["
212: + prefixedNameOfRef + "]");
213: }
214: doc = newDoc;
215: }
216: return doc;
217: }
218:
219: private void writeSilently(String err_path, String doc) {
220: try {
221: if (DEBUG) {
222: write(err_path, doc);
223: }
224: } catch (IOException e) {
225: }
226: }
227:
228: private void printReplacemant(String prefixedNameOfRef,
229: String replacement, int pos) {
230: if (DEBUG) {
231: System.out.println("prefixedNameOfRef = ["
232: + prefixedNameOfRef + "]; " + "replacement = ["
233: + replacement + "]; pos = " + pos);
234: }
235: }
236:
237: private String replaceAncorStarts(String doc) {
238: doc = doc.replaceAll(ANCOR_START_PATTERN, ANCOR_START_REAL);
239: return doc;
240: }
241:
242: private ReplaceCollection extractReplaces(String doc) {
243: StringBuffer buffer = new StringBuffer(doc);
244: ReplaceCollection replaceCollection = new ReplaceCollection();
245:
246: int startIndex = -1;
247: int endIndex = -1;
248: while ((startIndex = buffer
249: .indexOf(ANCOR_START, startIndex + 1)) >= 0) {
250: endIndex = endIndex == -1 ? startIndex : endIndex;
251: endIndex = buffer.indexOf(ANCOR_END, endIndex + 1);
252: String between = buffer.substring(startIndex, endIndex);
253:
254: int lastPeriodIndex = lastPeriodIndex(between);
255: String realNameOfRef = between.substring(
256: ANCOR_START.length()).trim()
257: + ANCOR_END;
258: String inner = between.substring(lastPeriodIndex + 1);
259:
260: System.out.println("between = " + between);
261: System.out.println("lastPeriodIndex = " + lastPeriodIndex);
262: System.out.println("realNameOfRef = " + realNameOfRef);
263:
264: inner = inner.replaceAll("\\s+", "_");
265: inner = inner.replaceAll(QUESTION_MARK_PATTERN,
266: QUESTION_MARK_ENCODED);
267: inner = inner.replaceAll("\\(", "_28");
268: inner = inner.replaceAll("\\)", "_29");
269: String nameOfRef = inner;
270:
271: String prefixedNameOfRef = prefixedNameOfRef(nameOfRef);
272: int indexOfRef = buffer.indexOf(prefixedNameOfRef);
273:
274: System.out.println("nameOfRef = " + nameOfRef);
275: System.out.println("indexOfRef = " + indexOfRef);
276:
277: if (indexOfRef < 0) {
278: throw new IllegalArgumentException(
279: "Cannot find prefixedNameOfRef "
280: + prefixedNameOfRef);
281: }
282:
283: if (replaceCollection.containsRealName(realNameOfRef)) {
284: break;
285: } else {
286: System.out.println("replace: nameOfRef = " + nameOfRef
287: + " with realNameOfRef = " + realNameOfRef);
288: replaceCollection.addReplace(realNameOfRef, nameOfRef);
289: }
290: }
291: return replaceCollection;
292: }
293:
294: private String prefixedNameOfRef(String nameOfRef) {
295: return REF_PREFIX + nameOfRef;
296: }
297:
298: private int lastPeriodIndex(String between) {
299: int lastPeriodIndex = -1;
300: int prevPeriodIndex;
301: int next = -1;
302:
303: int count = 0;
304: while ((next = between.indexOf('.', next + 1)) >= 0) {
305: count++;
306: lastPeriodIndex = next;
307: }
308:
309: prevPeriodIndex = lastPeriodIndex;
310:
311: if (lastPeriodIndex > 0
312: && !Character.isDigit(between
313: .charAt(lastPeriodIndex - 1))) {
314: lastPeriodIndex = -1;
315:
316: System.out.println("between = " + between);
317: System.out.println("count = " + count);
318: for (int i = 0; i < count - 1; i++) {
319: lastPeriodIndex = between.indexOf('.',
320: lastPeriodIndex + 1);
321: }
322: if (lastPeriodIndex == prevPeriodIndex) {
323: throw new IllegalArgumentException(
324: "lastPeriodIndex == prevPeriodIndex = "
325: + lastPeriodIndex);
326: }
327: }
328:
329: return lastPeriodIndex;
330: }
331:
332: private String readFileAsString() throws IOException {
333: File file = new File(in_path);
334:
335: long len = file.length();
336: if (len > Integer.MAX_VALUE) {
337: throw new RuntimeException(
338: "Cannot read whole file as string - too big");
339: }
340: byte[] bytes = new byte[((int) len)];
341:
342: FileInputStream inputStream = new FileInputStream(file);
343: inputStream.read(bytes);
344: inputStream.close();
345: return new String(bytes);
346:
347: }
348:
349: private static class ReplaceCollection {
350: public LinkedHashMap replaces = new LinkedHashMap();
351:
352: public void addReplace(String realNameOfRef, String nameOfRef) {
353: replaces.put(realNameOfRef, nameOfRef);
354: }
355:
356: public boolean containsRealName(String realNameOfRef) {
357: return replaces.containsKey(realNameOfRef);
358: }
359:
360: public LinkedHashMap getReplaces() {
361: return replaces;
362: }
363: }
364:
365: }
|