blob: 9466747eaa6dc09bb6dd856e3f2a125e4a17fd8c [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.myfaces.extension.scripting.doccompiler;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.nio.charset.Charset;
import java.util.Iterator;
/**
* A simple cross compile solution for the xslt mdtext conversion
* for the apache cms. It uses xslt as transformation language
*
* @author Werner Punz (latest modification by $Author$)
* @version $Revision$ $Date$
*/
public class XSLTDocCompiler
{
static final String docRootPath = "../../../src/site/xdoc";
static final String strTargetDir = "../../../src/site/mdtext";
static final String strXsltFile = "../../src/main/resources/xdocconversion.xslt";
static String currentPath = null;
static
{
ClassLoader loader = Thread.currentThread().getContextClassLoader();
try
{
currentPath = URLDecoder.decode(loader.getResource("./").getPath(),
Charset.defaultCharset().toString());
}
catch (UnsupportedEncodingException e)
{
}
}
public static void main(String... argv)
{
String[] fileEndings = {"xml"};
Iterator fileIter = FileUtils.iterateFiles(new File(FilenameUtils.normalize(currentPath + File.separator + docRootPath)), fileEndings, true);
while (fileIter.hasNext())
{
File toProcess = (File) fileIter.next();
transformFile(toProcess);
}
}
//code blocks must be at least 4 chars into the
static int handleCode(StringBuilder target, int pos, String[] lines)
{
pos++;
while (!lines[pos].contains("</code>"))
{
target.append(" ");
target.append(lines[pos]);
target.append("\n");
pos++;
}
return pos;
}
static int determinePrecedingBlanks(String in)
{
//we determine how many blanks are before the first < and we cut that from the rest
//of the table, that way we keep the formatting but do not run into the code issue mdtext has
char[] tokenizer = in.toCharArray();
int pos = 0;
for (; pos < tokenizer.length; pos++)
{
char token = tokenizer[pos];
if (!(token == ' '))
{
break;
}
}
return pos;
}
static String cutPrecedingBlanks(String in, int maxBlanks)
{
char[] tokenizer = in.toCharArray();
Character token = null;
int cnt = 0;
for (; cnt <= maxBlanks && cnt < tokenizer.length; cnt++)
{
token = tokenizer[cnt];
if (!token.equals(' '))
{
break;
}
}
StringBuilder finalStr = new StringBuilder(in.length());
while (cnt < tokenizer.length)
{
finalStr.append(tokenizer[cnt]);
cnt++;
}
return finalStr.toString();
}
static int handleUL(StringBuilder target, int pos, String[] lines, int indendation)
{
int precedingBlanks = Math.max(0, determinePrecedingBlanks(lines[pos]) - indendation);
target.append(cutPrecedingBlanks(lines[pos], precedingBlanks));
target.append("\n");
//special case same line ul is closed
if (lines[pos].contains("</ul>"))
{
return pos;
}
pos++;
//TODO nesting
while (pos < lines.length && !lines[pos].contains("</ul>"))
{
if (lines[pos].contains("<ul>"))
{
pos = handleUL(target, pos, lines, precedingBlanks);
} else
{
target.append(cutPrecedingBlanks(lines[pos], precedingBlanks));
target.append("\n");
}
pos++;
}
if (pos < lines.length)
{
target.append(cutPrecedingBlanks(lines[pos], precedingBlanks));
target.append("\n");
}
return pos;
}
static int handleTable(StringBuilder target, int pos, String[] lines, int indentation)
{
int precedingBlanks = Math.max(0, determinePrecedingBlanks(lines[pos]) - indentation);
target.append(cutPrecedingBlanks(lines[pos], precedingBlanks));
target.append("\n");
if (lines[pos].contains("</table>"))
{
return pos;
}
pos++;
while (pos < lines.length && !lines[pos].contains("</table>"))
{
if (lines[pos].contains("<table>"))
{
pos = handleTable(target, pos, lines, precedingBlanks);
} else
{
target.append(cutPrecedingBlanks(lines[pos], precedingBlanks));
target.append("\n");
}
pos++;
}
target.append(cutPrecedingBlanks(lines[pos], precedingBlanks));
target.append("\n");
return pos;
}
static String formatter(String in)
{
StringBuilder target = new StringBuilder();
target.append("<!--\n" +
" Licensed to the Apache Software Foundation (ASF) under one\n" +
" or more contributor license agreements. See the NOTICE file\n" +
" distributed with this work for additional information\n" +
" regarding copyright ownership. The ASF licenses this file\n" +
" to you under the Apache License, Version 2.0 (the\n" +
" \"License\"); you may not use this file except in compliance\n" +
" with the License. You may obtain a copy of the License at\n" +
"\n" +
" http://www.apache.org/licenses/LICENSE-2.0\n" +
"\n" +
" Unless required by applicable law or agreed to in writing,\n" +
" software distributed under the License is distributed on an\n" +
" \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n" +
" KIND, either express or implied. See the License for the\n" +
" specific language governing permissions and limitations\n" +
" under the License.\n" +
"-->");
String[] lines = in.split("\n+");
for (int cnt = 0; cnt < lines.length; cnt++)
{
String line = lines[cnt];
//no inline xml/html formatting
if (line.contains("<code>"))
{
cnt = handleCode(target, cnt, lines);
} else if (line.contains("<table>"))
{
cnt = handleTable(target, cnt, lines, 0);
} else if (line.contains("<ul>"))
{
cnt = handleUL(target, cnt, lines, 0);
} else if (line.matches("\\s+[^#]+"))
{
line = line.replaceAll("\\s+", " ");
} else if (line.matches("\\s+#.+"))
{
line = line.replaceAll("^\\s+", "");
}
if (!line.contains("<code>") && !line.contains("<table>") && !line.contains("<ul>"))
{
target.append(line);
target.append("\n");
}
}
return target.toString();
}
private static void transformFile(File xmlFile)
{
//File xmlFile = new File(strXmlFile);
File xsltFile = new File(FilenameUtils.normalize(currentPath + File.separator + strXsltFile));
// JAXP liest Daten über die Source-Schnittstelle
Source xmlSource = new StreamSource(xmlFile);
Source xsltSource = new StreamSource(xsltFile);
// das Factory-Pattern unterstützt verschiedene XSLT-Prozessoren
TransformerFactory transFact =
TransformerFactory.newInstance();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try
{
Transformer trans = transFact.newTransformer(xsltSource);
trans.transform(xmlSource, new StreamResult(baos));
String result = baos.toString("UTF-8");
String fileName = FilenameUtils.normalize(currentPath + File.separator + strTargetDir + File.separator + xmlFile.getName().split("\\.")[0] + ".mdtext");
File target = new File(fileName);
FileUtils.deleteQuietly(target);
result = formatter(result);
FileUtils.writeStringToFile(target, result);
}
catch (TransformerException e)
{
e.printStackTrace();
}
catch (UnsupportedEncodingException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}