/*
GNU General Public License
CacheWolf is a software for PocketPC, Win and Linux that
enables paperless caching.
It supports the sites geocaching.com and opencaching.de
Copyright (C) 2006 CacheWolf development team
See http://www.cachewolf.de/ for more information.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
package CacheWolf.exp;
import CacheWolf.MainForm;
import CacheWolf.MainTab;
import CacheWolf.Preferences;
import CacheWolf.controls.InfoBox;
import CacheWolf.database.CacheDB;
import CacheWolf.database.CacheHolder;
import CacheWolf.database.CacheType;
import CacheWolf.utils.MyLocale;
import HTML.Template;
import com.stevesoft.ewe_pat.Regex;
import ewe.filechooser.FileChooser;
import ewe.filechooser.FileChooserBase;
import ewe.io.AsciiCodec;
import ewe.io.BufferedWriter;
import ewe.io.File;
import ewe.io.FileWriter;
import ewe.io.IOException;
import ewe.io.JavaUtf8Codec;
import ewe.io.PrintWriter;
import ewe.io.TextCodec;
import ewe.ui.FormBase;
import ewe.ui.ProgressBarForm;
import ewe.util.ByteArray;
import ewe.util.CharArray;
import ewe.util.Enumeration;
import ewe.util.Hashtable;
import ewe.util.Vector;
/**
* @author Kalle class to export cachedata using a template
*/
class TplFilter implements HTML.Tmpl.Filter {
private int type = SCALAR;
private String newLine = "\n";
TextCodec codec = new AsciiCodec(); // codec = new AsciiCodec(AsciiCodec.STRIP_CR);
boolean simplify = false;
String badChars;
String decSep = ".";
int shortNameLength = 30;
int shortWaypointLength = 3;
int noOfLogs = -1; // means all
boolean single = true;
int formatModifier = 0;
int sortedBy = -1;
boolean getAddiWp = false;
boolean getMainWp = false;
boolean getParking = false;
int copyCacheImages = 0;
Hashtable additionalVarParams = new Hashtable();
String userValue = "";
String out = "*.gpx";
public TplFilter() {
return;
}
public int format() {
return this.type;
}
public String parse(String t) {
Regex rex, rex1;
String param, value;
// Filter comments <#-- and -->
rex = new Regex("<#--.*-->", "");
t = rex.replaceAll(t);
// search for parameters
rex = new Regex("(?i)<tmpl_par.*>");
rex.search(t);
if (rex.didMatch()) {
// get parameter
rex1 = new Regex("(?i)name=\"(.*)\"\\svalue=\"(.*)\"[?\\s>]");
rex1.search(t);
param = rex1.stringMatched(1);
value = rex1.stringMatched(2);
if (param.equals("charset")) {
if (value.equals("ASCII")) {
codec = new AsciiCodec();
simplify = true;
} else if (value.equals("UTF8")) {
codec = new JavaUtf8Codec();
} else {
codec = new NoCodec();
}
} else if (param.equals("badchars")) {
badChars = value;
} else if (param.equals("newline")) {
newLine = "";
if (value.indexOf("CR") >= 0)
newLine += "\r";
if (value.indexOf("LF") >= 0)
newLine += "\n";
} else if (param.equals("decsep")) {
decSep = value;
} else if (param.equals("ShortNameLength")) {
shortNameLength = Integer.valueOf(value).intValue();
} else if (param.equals("WaypointLength")) {
shortWaypointLength = Integer.valueOf(value).intValue();
} else if (param.equals("NrLogs")) {
noOfLogs = Integer.valueOf(value).intValue();
} else if (param.equals("singleFile")) {
single = value.equals("yes") ? true : false;
} else if (param.equals("formatModifier")) {
formatModifier = Integer.valueOf(value).intValue();
} else if (param.equals("Out")) {
out = value;
} else if (param.equals("takeOnlyWp")) {
if (value.equals("main")) {
getMainWp = true;
} else if (value.equals("addi")) {
getAddiWp = true;
} else if (value.equals("parking")) {
getParking = true;
}
} else if (param.equals("sortedBy")) {
sortedBy = Integer.valueOf(value).intValue();
} else if (param.equals("CopyCacheImages")) {
if (value.equals("yes"))
copyCacheImages = 1;
if (value.equals("CBX"))
copyCacheImages = 2;
} else if (param.startsWith("input")) {
String par = param.substring(5);
InfoBox inf = new InfoBox("Eingabe", par, InfoBox.INPUT);
inf.setInput(value);
if (inf.execute() == FormBase.IDOK) {
String input = inf.getInput();
if (input.length() > 0 && !input.equalsIgnoreCase("no")) {
additionalVarParams.put(par, input);
}
}
} else if (param.startsWith("const")) {
additionalVarParams.put(param.substring(5), value);
}
return "";
}
if (formatModifier == 0) {
// for gpx output
// Filter newlines
rex = new Regex("(?m)\n$", "");
t = rex.replaceAll(t);
// replace <br> or <br /> with newline
rex = new Regex("<br.*>", "");
rex.search(t);
if (rex.didMatch()) {
t = rex.replaceAll(t);
t += newLine;
}
}
return t;
}
public String[] parse(String[] t) {
throw new UnsupportedOperationException();
}
}
public class TPLExporter {
CacheDB cacheDB;
String tplFile;
String expName;
Regex rex = null;
private static GarminMap gm = null;
public TPLExporter(String tpl) {
cacheDB = MainForm.profile.cacheDB;
tplFile = tpl;
File tmpFile = new File(tpl);
expName = tmpFile.getName();
expName = expName.substring(0, expName.indexOf("."));
gm = new GarminMap();
}
public void doIt() {
ProgressBarForm pbf = new ProgressBarForm();
ewe.sys.Handle h = new ewe.sys.Handle();
int counter = cacheDB.countVisible();
pbf.showMainTask = false;
pbf.setTask(h, "Exporting ...");
pbf.exec();
try {
TplFilter myFilter = new TplFilter();
Hashtable args = new Hashtable();
// args.put("debug", "true");
args.put("filename", tplFile);
args.put("case_sensitive", "true");
args.put("loop_context_vars", Boolean.TRUE);
args.put("max_includes", new Integer(5));
args.put("filter", myFilter);
Template tpl = new Template(args);
FileChooser fc = new FileChooser(FileChooserBase.SAVE, Preferences.itself().getExportPath(expName));
fc.setTitle("Select target file:");
fc.addMask(myFilter.out);
if (fc.execute() == FormBase.IDCANCEL) {
pbf.exit(0);
return;
}
File saveTo = fc.getChosenFile();
Preferences.itself().setExportPref(expName, saveTo.getPath());
if (myFilter.sortedBy != -1) {
MainTab.itself.tablePanel.myTableModel.sortTable(myFilter.sortedBy, true);
}
Regex dec = new Regex("[,.]", myFilter.decSep);
if (myFilter.badChars != null)
rex = new Regex("[" + myFilter.badChars + "]", "");
Vector cache_index = new Vector();
String imgExpName = "";
if (myFilter.copyCacheImages == 1)
imgExpName = expName;
if (myFilter.copyCacheImages == 2)
imgExpName = expName + "*";
TemplateTable tt = new TemplateTable();
for (int i = 0; i < counter; i++) {
CacheHolder ch = cacheDB.get(i);
if (ch.isVisible() && (ch.getWpt().isValid() || myFilter.formatModifier > 0)) {
boolean get = true;
if (myFilter.getAddiWp) {
get = ch.isAddiWpt();
} else if (myFilter.getMainWp) {
get = !ch.isAddiWpt();
} else if (myFilter.getParking) {
get = (ch.getType() == CacheType.CW_TYPE_PARKING)// parking
|| (!ch.isAddiWpt() && !hasParking(ch));// oder main ohne Parkplatz
}
if (get) {
h.progress = (float) i / (float) counter;
h.changed();
try {
tt.set(ch);
Hashtable varParams = tt.toHashtable(dec, rex, myFilter.shortWaypointLength, myFilter.shortNameLength, myFilter.noOfLogs, myFilter.simplify, gm, false, myFilter.formatModifier, imgExpName);
Enumeration e = myFilter.additionalVarParams.keys();
while (e.hasMoreElements()) {
String key = (String) e.nextElement();
Object value = myFilter.additionalVarParams.get(key);
varParams.put(key, value);
}
if (myFilter.single) {
cache_index.add(varParams);
} else {
tpl.setParams(varParams);
String ext = (myFilter.out.substring(myFilter.out.lastIndexOf(".")).toLowerCase() + " ").trim();
FileWriter fw = new FileWriter(saveTo.getPath() + ch.getCode() + ext);
fw.codec = myFilter.codec;
PrintWriter detfile = new PrintWriter(new BufferedWriter(fw));
tpl.printTo(detfile);
detfile.close();
}
} catch (Exception e) {
Preferences.itself().log("[TplExporter:doIt]" + ch.getCode(), e, true);
}
}
}
}
if (myFilter.single) {
tpl.setParam("cache_index", cache_index);
FileWriter fw = new FileWriter(saveTo);
fw.codec = myFilter.codec;
PrintWriter detfile = new PrintWriter(new BufferedWriter(fw));
tpl.printTo(detfile);
// oder detfile.print(tpl.output());
detfile.close();
}
} catch (Exception e) {
Preferences.itself().log("[TplExporter:doIt]", e, true);
} catch (OutOfMemoryError e) {
new InfoBox(MyLocale.getMsg(5500, "Error"), "Not enough memory available to load all cache data (incl. description and logs)\nexport aborted\nFilter caches to minimise memory needed for TPL-Export\nWe recommend to restart CacheWolf now")
.wait(FormBase.OKB);
}
pbf.exit(0);
}
private boolean hasParking(CacheHolder ch) {
boolean ret = false;
if (ch.hasAddiWpt()) {
for (int i = 0; i < ch.addiWpts.size(); i++) {
CacheHolder chwp = (CacheHolder) ch.addiWpts.get(i);
if (chwp.getType() == CacheType.CW_TYPE_PARKING)
return true;
}
}
return ret;
}
}
// ##################################################################
class NoCodec implements TextCodec {
// ##################################################################
/**
* This is a creation option. It specifies that CR characters should be removed when encoding text into UTF.
*/
public static final int STRIP_CR_ON_DECODE = 0x1;
/**
* This is a creation option. It specifies that CR characters should be removed when decoding text from UTF.
*/
public static final int STRIP_CR_ON_ENCODE = 0x2;
/**
* This is a creation option. It specifies that CR characters should be removed when decoding text from UTF AND encoding text to UTF.
*/
public static final int STRIP_CR = STRIP_CR_ON_DECODE | STRIP_CR_ON_ENCODE;
private int flags = 0;
// ===================================================================
public NoCodec(int options)
// ===================================================================
{
flags = options;
}
// ===================================================================
public NoCodec()
// ===================================================================
{
this(0);
}
// ===================================================================
public ByteArray encodeText(char[] text, int start, int length, boolean endOfData, ByteArray dest) throws IOException
// ===================================================================
{
if (dest == null)
dest = new ByteArray();
int size = length == 0 ? 2 : 2 + text.length * 2;
if (dest.data == null || dest.data.length < size)
dest.data = new byte[size];
byte[] destination = dest.data;
int s = 0;
if (length > 0) {
destination[s++] = (byte) 0xFF;
destination[s++] = (byte) 0xFE;
}
for (int i = 0; i < length; i++) {
char c = text[i + start];
if (c == 13 && ((flags & STRIP_CR_ON_ENCODE) != 0))
continue;
destination[s++] = (byte) (c & 0xFF);
destination[s++] = (byte) ((c >> 8) & 0xFF);
}
dest.length = s;
return dest;
}
// ===================================================================
public CharArray decodeText(byte[] encoded, int start, int length, boolean endOfData, CharArray dest) throws IOException
// ===================================================================
{
if (dest == null)
dest = new CharArray();
dest.length = 0;
return dest;
}
// ===================================================================
public void closeCodec() throws IOException
// ===================================================================
{
}
// ===================================================================
public Object getCopy()
// ===================================================================
{
return new NoCodec(flags);
}
// ##################################################################
}
// ##################################################################